Cataclysm BN
Character Class Referenceabstract

#include <character.h>

Inheritance diagram for Character:
Creature visitable< Character > player avatar npc standard_npc

Classes

struct  has_mission_item_filter
 

Public Types

enum  water_tolerance { WT_IGNORED = 0 , WT_NEUTRAL , WT_GOOD , NUM_WATER_TOLERANCE }
 
using trap_map = std::map< tripoint, std::string >
 
- Public Types inherited from Creature
enum  Attitude : int { A_HOSTILE , A_NEUTRAL , A_FRIENDLY , A_ANY }
 Simplified attitude towards any creature: hostile - hate, want to kill, etc. More...
 

Public Member Functions

 Character (const Character &)=delete
 
Characteroperator= (const Character &)=delete
 
 ~Character () override
 
Characteras_character () override
 
const Characteras_character () const override
 
character_id getID () const
 
void setID (character_id i, bool force=false)
 
bool is_dead_state () const override
 Returns true if the character should be dead. More...
 
field_type_id bloodType () const override
 
field_type_id gibType () const override
 
bool is_warm () const override
 
bool in_species (const species_id &spec) const override
 
const std::string & symbol () const override
 
virtual int get_str () const
 Getters for stats exclusive to characters. More...
 
virtual int get_dex () const
 
virtual int get_per () const
 
virtual int get_int () const
 
virtual int get_str_base () const
 
virtual int get_dex_base () const
 
virtual int get_per_base () const
 
virtual int get_int_base () const
 
virtual int get_str_bonus () const
 
virtual int get_dex_bonus () const
 
virtual int get_per_bonus () const
 
virtual int get_int_bonus () const
 
int get_speed () const override
 
virtual int ranged_dex_mod () const
 
virtual int ranged_per_mod () const
 
virtual void set_str_bonus (int nstr)
 Setters for stats exclusive to characters. More...
 
virtual void set_dex_bonus (int ndex)
 
virtual void set_per_bonus (int nper)
 
virtual void set_int_bonus (int nint)
 
virtual void mod_str_bonus (int nstr)
 
virtual void mod_dex_bonus (int ndex)
 
virtual void mod_per_bonus (int nper)
 
virtual void mod_int_bonus (int nint)
 
void print_health () const
 
virtual int get_healthy () const
 Getters for health values exclusive to characters. More...
 
virtual int get_healthy_mod () const
 
virtual void mod_healthy (int nhealthy)
 Modifiers for health values exclusive to characters. More...
 
virtual void mod_healthy_mod (int nhealthy_mod, int cap)
 
virtual void set_healthy (int nhealthy)
 Setters for health values exclusive to characters. More...
 
virtual void set_healthy_mod (int nhealthy_mod)
 
int get_stored_kcal () const
 Getter for need values exclusive to characters. More...
 
int max_stored_kcal () const
 
float get_kcal_percent () const
 
int get_thirst () const
 
std::pair< std::string, nc_colorget_thirst_description () const
 
std::pair< std::string, nc_colorget_hunger_description () const
 
std::pair< std::string, nc_colorget_fatigue_description () const
 
int get_fatigue () const
 
int get_sleep_deprivation () const
 
std::pair< std::string, nc_colorget_pain_description () const override
 
virtual void mod_stored_kcal (int nkcal)
 Modifiers for need values exclusive to characters. More...
 
virtual void mod_stored_nutr (int nnutr)
 
virtual void mod_thirst (int nthirst)
 
virtual void mod_fatigue (int nfatigue)
 
virtual void mod_sleep_deprivation (int nsleep_deprivation)
 
virtual void set_stored_kcal (int kcal)
 Setters for need values exclusive to characters. More...
 
virtual void set_thirst (int nthirst)
 
virtual void set_fatigue (int nfatigue)
 
virtual void set_sleep_deprivation (int nsleep_deprivation)
 
void mod_stat (const std::string &stat, float modifier) override
 
m_size get_size () const override
 Get size class of character. More...
 
void recalculate_size ()
 Recalculate size class of character. More...
 
void recalc_speed_bonus ()
 Calculates the various speed bonuses we will get from mutations, etc. More...
 
std::string disp_name (bool possessive=false, bool capitalize_first=false) const override
 Returns either "you" or the player's name. More...
 
std::string skin_name () const override
 Returns the name of the player's outer layer, e.g. More...
 
virtual factionget_faction () const
 
void set_fac_id (const std::string &my_fac_id)
 
float get_dodge_base () const override
 Combat getters. More...
 
float get_hit_base () const override
 
float get_dodge () const override
 
float dodge_roll () override
 
float get_melee () const override
 Returns melee skill level, to be used to throttle dodge practice. More...
 
const tripointpos () const override
 
int sight_range (int light_level) const override
 Returns the player's sight range. More...
 
int unimpaired_range () const
 Returns the player maximum vision range factoring in mutations, diseases, and other effects. More...
 
bool overmap_los (const tripoint_abs_omt &omt, int sight_points)
 Returns true if overmap tile is within player line-of-sight. More...
 
int overmap_sight_range (int light_level) const
 Returns the distance the player can see on the overmap. More...
 
int clairvoyance () const
 Returns the distance the player can see through walls. More...
 
bool sight_impaired () const
 Returns true if the player has some form of impaired sight. More...
 
bool has_alarm_clock () const
 Returns true if the player or their vehicle has an alarm clock. More...
 
bool has_watch () const
 Returns true if the player or their vehicle has a watch. More...
 
void action_taken ()
 Called after every action, invalidates player caches. More...
 
bool is_on_ground () const override
 Returns true if the player is knocked over or has broken legs. More...
 
int swim_speed () const
 Returns the player's speed for swimming across water tiles. More...
 
void add_miss_reason (const std::string &reason, unsigned int weight)
 Adds a reason for why the player would miss a melee attack. More...
 
void clear_miss_reasons ()
 Clears the list of reasons for why the player would miss a melee attack. More...
 
std::string get_miss_reason ()
 Returns an explanation for why the player would miss a melee attack. More...
 
void knock_back_to (const tripoint &to) override
 Knocks the character to a specified tile. More...
 
float fall_damage_mod () const override
 Returns multiplier on fall damage at low velocity (knockback/pit/1 z-level, not 5 z-levels) More...
 
int impact (int force, const tripoint &pos) override
 Deals falling/collision damage with terrain/creature at pos. More...
 
int hp_percentage () const override
 Returns overall % of HP remaining. More...
 
void regen (int rate_multiplier)
 Handles passive regeneration of pain and maybe hp. More...
 
void enforce_minimum_healing ()
 
itembest_quality_item (const quality_id &qual)
 get best quality item that this character has More...
 
virtual void update_health (int external_modifiers=0)
 Handles health fluctuations over time. More...
 
void update_body ()
 Updates all "biology" by one turn. More...
 
void update_body (const time_point &from, const time_point &to)
 Updates all "biology" as if time between from and to passed. More...
 
void update_stomach (const time_point &from, const time_point &to)
 Updates the stomach to give accurate hunger messages. More...
 
void update_needs (int rate_multiplier)
 Increases hunger, thirst, fatigue and stimulants wearing off. More...
 
needs_rates calc_needs_rates () const
 
void check_needs_extremes ()
 Kills the player if too hungry, stimmed up etc., forces tired player to sleep and prints warnings. More...
 
bool is_hibernating () const
 Returns if the player has hibernation mutation and is asleep and well fed. More...
 
void update_bodytemp (const map &m, const weather_manager &weather)
 Maintains body temperature. More...
 
void temp_equalizer (const bodypart_id &bp1, const bodypart_id &bp2)
 Equalizes heat between body parts. More...
 
int blood_loss (const bodypart_id &bp) const
 Define blood loss (in percents) More...
 
void reset_bonuses () override
 Resets the value of all bonus fields to 0. More...
 
void reset_stats () override
 Resets stats, and applies effects in an idempotent manner. More...
 
void reset () override
 Handles stat and bonus reset. More...
 
void environmental_revert_effect ()
 
void reset_encumbrance ()
 Recalculates encumbrance cache. More...
 
int encumb (body_part bp) const
 Returns ENC provided by armor, etc. More...
 
units::mass get_weight () const override
 Returns body weight plus weight of inventory and worn/wielded items. More...
 
char_encumbrance_data get_encumbrance () const
 Get encumbrance for all body parts. More...
 
char_encumbrance_data get_encumbrance (const item &new_item) const
 Get encumbrance for all body parts as if new_item was also worn. More...
 
int extraEncumbrance (layer_level level, int bp) const
 Get encumbrance penalty per layer & body part. More...
 
bool is_wearing_power_armor (bool *hasHelmet=nullptr) const
 Returns true if the character is wearing power armor. More...
 
bool is_wearing_active_power_armor () const
 Returns true if the character is wearing active power. More...
 
bool is_wearing_active_optcloak () const
 Returns true if the player is wearing an active optical cloak. More...
 
bool in_climate_control ()
 Returns true if the player is in a climate controlled area or armor. More...
 
bool is_blind () const
 Returns true if the player isn't able to see. More...
 
bool is_invisible () const
 
int visibility (bool check_color=false, int stillness=0) const
 Checks is_invisible() as well as other factors. More...
 
float active_light () const
 Returns character luminosity based on the brightest active item they are carrying. More...
 
bool sees_with_specials (const Creature &critter) const
 
body_part_set exclusive_flag_coverage (const std::string &flag) const
 Bitset of all the body parts covered only with items with flag (or nothing) More...
 
bool move_effects (bool attacking) override
 Processes effects which may prevent the Character from moving (bear traps, crushed, etc.). More...
 
void wait_effects ()
 
bool movement_mode_is (character_movemode mode) const
 Check against the character's current movement mode. More...
 
character_movemode get_movement_mode () const
 
virtual void set_movement_mode (character_movemode mode)=0
 
void expose_to_disease (diseasetype_id dis_type)
 Determine if character is susceptible to dis_type and if so apply the symptoms. More...
 
void process_turn () override
 Handles end-of-turn processing. More...
 
void process_effects_internal () override
 Processes human-specific effects of effects before calling Creature::process_effects(). More...
 
void hardcoded_effects (effect &it)
 Handles the still hard-coded effects. More...
 
void process_one_effect (effect &it, bool is_new) override
 Processes human-specific effects of an effect. More...
 
void process_items ()
 Process active items. More...
 
void recalc_hp ()
 Recalculates HP after a change to max strength. More...
 
void calc_all_parts_hp (float hp_mod=0.0, float hp_adjust=0.0, int str_max=0)
 Sets hp for all body parts. More...
 
void recalc_sight_limits ()
 Modifies the player's sight values Must be called when any of the following change: This must be called when any of the following change: More...
 
float get_vision_threshold (float light_level) const
 Returns the apparent light level at which the player can see. More...
 
void flag_encumbrance ()
 Flag encumbrance for updating. More...
 
void check_item_encumbrance_flag ()
 Checks worn items for the "RESET_ENCUMBRANCE" flag, which indicates that encumbrance may have changed and require recalculating. More...
 
bool natural_attack_restricted_on (const bodypart_id &bp) const
 Returns true if the character is wearing something on the entered body_part, ignoring items with the ALLOWS_NATURAL_ATTACKS flag. More...
 
bool can_use_grab_break_tec (const item &weap) const
 Returns true if the player is able to use a grab breaking technique. More...
 
bool can_miss_recovery (const item &weap) const
 Returns true if the player is able to use a miss recovery technique. More...
 
bool is_quiet () const
 Returns true if the player has quiet melee attacks. More...
 
bool is_stealthy () const
 Returns true if the player has stealthy movement. More...
 
bool uncanny_dodge () override
 Handles the uncanny dodge bionic and effects, returns true if the creature successfully dodges. More...
 
bool block_ranged_hit (Creature *source, bodypart_id &bp_hit, damage_instance &dam) override
 Checks for chance that a ranged attack will hit other armor along the way. More...
 
bool block_hit (Creature *source, bodypart_id &bp_hit, damage_instance &dam) override
 Checks for valid block abilities and reduces damage accordingly. More...
 
itembest_shield ()
 Returns the best item for blocking with. More...
 
bool handle_melee_wear (item &shield, float wear_multiplier=1.0f)
 Calculates melee weapon wear-and-tear through use, returns true if item is destroyed. More...
 
matec_id pick_technique (Creature &t, const item &weap, bool crit, bool dodge_counter, bool block_counter)
 Returns a random valid technique. More...
 
void perform_technique (const ma_technique &technique, Creature &t, damage_instance &di, int &move_cost)
 
void melee_attack (Creature &t, bool allow_special, const matec_id *force_technique=nullptr, bool allow_unarmed=true)
 Sets up a melee attack and handles melee attack function calls. More...
 
std::string melee_special_effects (Creature &t, damage_instance &d, item &weap)
 Handles combat effects, returns a string of any valid combat effect messages. More...
 
void perform_special_attacks (Creature &t, dealt_damage_instance &dealt_dam)
 Performs special attacks and their effects (poisonous, stinger, etc.) More...
 
void reach_attack (const tripoint &p)
 Handles reach melee attack on point p. More...
 
float stability_roll () const override
 Returns value of player's stable footing. More...
 
std::vector< special_attackmutation_attacks (Creature &t) const
 Returns a vector of valid mutation attacks. More...
 
float bonus_damage (bool random) const
 Returns the bonus bashing damage the player deals based on their stats. More...
 
float get_melee_hit_base () const
 Returns weapon skill. More...
 
float hit_roll () const override
 Returns the player's basic hit roll that is compared to the target's dodge roll. More...
 
double crit_chance (float roll_hit, float target_dodge, const item &weap) const
 Returns the chance to critical given a hit roll and target's dodge roll. More...
 
bool scored_crit (float target_dodge, const item &weap) const
 Returns true if the player scores a critical hit. More...
 
int attack_cost (const item &weap) const
 Returns cost (in moves) of attacking with given item (no modifiers, like stuck) More...
 
float get_hit_weapon (const item &weap) const
 Gets melee accuracy component from weapon+skills. More...
 
void roll_all_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds all 3 types of physical damage to instance. More...
 
void roll_bash_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds player's total bash damage to the damage instance. More...
 
void roll_cut_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds player's total cut damage to the damage instance. More...
 
void roll_stab_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds player's total stab damage to the damage instance. More...
 
void on_dodge (Creature *source, int difficulty) override
 This creature just dodged an attack - possibly special/ranged attack - from source. More...
 
void on_hit (Creature *source, bodypart_id bp_hit, dealt_projectile_attack const *proj) override
 This creature just got hit by an attack - possibly special/ranged attack - from source. More...
 
void did_hit (Creature &target)
 Handles special effects when the Character hits a Creature. More...
 
void apply_damage (Creature *source, bodypart_id hurt, int dam, bool bypass_med=false) override
 Actually hurt the player, hurts a body_part directly, no armor reduction. More...
 
dealt_damage_instance deal_damage (Creature *source, bodypart_id bp, const damage_instance &d) override
 Calls Creature::deal_damage and handles damaged effects (waking up, etc.) More...
 
int reduce_healing_effect (const efftype_id &eff_id, int remove_med, const bodypart_id &hurt)
 Reduce healing effect intensity, return initial intensity of the effect. More...
 
void cough (bool harmful=false, int loudness=4)
 
void passive_absorb_hit (const bodypart_id &bp, damage_unit &du) const
 Check for relevant passive, non-clothing that can absorb damage, and reduce by specified damage unit. More...
 
void absorb_hit (const bodypart_id &bp, damage_instance &dam) override
 Runs through all bionics and armor on a part and reduces damage through their armor_absorb. More...
 
bool armor_absorb (damage_unit &du, item &armor)
 Reduces and mutates du, prints messages about armor taking damage. More...
 
float bionic_armor_bonus (const bodypart_id &bp, damage_type dt) const
 Check for passive bionics that provide armor, and returns the armor bonus This is called from player::passive_absorb_hit. More...
 
int mabuff_armor_bonus (damage_type type) const
 Returns the armor bonus against given type from martial arts buffs. More...
 
std::map< bodypart_id, int > get_armor_fire (const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
 Returns overall fire resistance. More...
 
bool has_trait (const trait_id &b) const override
 Returns true if the player has the entered trait. More...
 
bool has_base_trait (const trait_id &b) const
 Returns true if the player has the entered starting trait. More...
 
bool has_trait_flag (const std::string &b) const
 Returns true if player has a trait with a flag. More...
 
bool has_opposite_trait (const trait_id &flag) const
 Returns true if character has a trait which cancels the entered trait. More...
 
void toggle_trait (const trait_id &)
 Toggles a trait on the player and in their mutation list. More...
 
void set_mutation (const trait_id &)
 Add or removes a mutation on the player, but does not trigger mutation loss/gain effects. More...
 
void unset_mutation (const trait_id &)
 
void switch_mutations (const trait_id &switched, const trait_id &target, bool start_powered)
 Unset switched mutation and set target mutation instead. More...
 
void activate_mutation (const trait_id &mutation)
 
void deactivate_mutation (const trait_id &mut)
 
void mutation_spend_resources (const trait_id &mut)
 Removes the appropriate costs (NOTE: will reapply mods & recalc sightlines in case of newly activated mutation). More...
 
bool can_mount (const monster &critter) const
 
void mount_creature (monster &z)
 
bool is_mounted () const
 
bool check_mount_will_move (const tripoint &dest_loc)
 
bool check_mount_is_spooked ()
 
void dismount ()
 
void forced_dismount ()
 
bool is_deaf () const
 
bool has_two_arms () const
 Returns true if the player has two functioning arms. More...
 
int get_working_arm_count () const
 Returns the number of functioning arms. More...
 
int get_working_leg_count () const
 Returns the number of functioning legs. More...
 
bool is_limb_disabled (const bodypart_id &limb) const
 Returns true if the limb is disabled(12.5% or less hp) More...
 
bool is_limb_hindered (hp_part limb) const
 Returns true if the limb is hindered(40% or less hp) More...
 
bool is_limb_broken (const bodypart_id &limb) const
 Returns true if the limb is broken. More...
 
bool can_run ()
 source of truth of whether a Character can run More...
 
void hurtall (int dam, Creature *source, bool disturb=true)
 Hurts all body parts for dam, no armor reduction. More...
 
int hitall (int dam, int vary, Creature *source)
 Harms all body parts for dam, with armor reduction. More...
 
void on_hurt (Creature *source, bool disturb=true)
 Handles effects that happen when the player is damaged and aware of the fact. More...
 
void heal (const bodypart_id &healed, int dam)
 Heals a body_part for dam. More...
 
void healall (int dam)
 Heals all body parts for dam. More...
 
hp_part body_window (const std::string &menu_header, bool show_all, bool precise, int normal_bonus, int head_bonus, int torso_bonus, float bleed, float bite, float infect, float bandage_power, float disinfectant_power) const
 Displays menu with body part hp, optionally with hp estimation after healing. More...
 
nc_color limb_color (const bodypart_id &bp, bool bleed, bool bite, bool infect) const
 
bool made_of (const material_id &m) const override
 
bool made_of_any (const std::set< material_id > &ms) const override
 
int posx () const override
 
int posy () const override
 
int posz () const override
 
void setx (int x)
 
void sety (int y)
 
void setz (int z)
 
void setpos (const tripoint &p) override
 
virtual tripoint global_square_location () const
 Global position, expressed in map square coordinate system (the most detailed coordinate system), used by the map. More...
 
tripoint global_sm_location () const
 Returns the location of the player in global submap coordinates. More...
 
tripoint_abs_omt global_omt_location () const
 Returns the location of the player in global overmap terrain coordinates. More...
 
void recalculate_enchantment_cache ()
 
void rebuild_mutation_cache ()
 
double bonus_from_enchantments (double base, enchant_vals::mod value, bool round=false) const
 Calculate bonus from enchantments for given base value. More...
 
bool has_mabuff (const mabuff_id &buff_id) const
 Returns true if the player has any martial arts buffs attached. More...
 
bool has_grab_break_tec () const override
 Returns true if the player has a grab breaking technique available. More...
 
float mabuff_tohit_bonus () const
 Returns the to hit bonus from martial arts buffs. More...
 
float mabuff_dodge_bonus () const
 Returns the dodge bonus from martial arts buffs. More...
 
int mabuff_block_bonus () const
 Returns the block bonus from martial arts buffs. More...
 
int mabuff_speed_bonus () const
 Returns the speed bonus from martial arts buffs. More...
 
int mabuff_arpen_bonus (damage_type type) const
 Returns the arpen bonus from martial arts buffs. More...
 
float mabuff_damage_mult (damage_type type) const
 Returns the damage multiplier to given type from martial arts buffs. More...
 
int mabuff_damage_bonus (damage_type type) const
 Returns the flat damage bonus to given type from martial arts buffs, applied after the multiplier. More...
 
int mabuff_attack_cost_penalty () const
 Returns the flat penalty to move cost of attacks. More...
 
float mabuff_attack_cost_mult () const
 Returns the multiplier on move cost of attacks. More...
 
void mutation_effect (const trait_id &mut)
 Handles things like removal of armor, etc. More...
 
void mutation_loss_effect (const trait_id &mut)
 Handles what happens when you lose a mutation. More...
 
bool has_active_mutation (const trait_id &b) const
 
void mutate ()
 Picks a random valid mutation and gives it to the Character, possibly removing/changing others along the way. More...
 
bool mutation_ok (const trait_id &mutation, bool force_good, bool force_bad) const
 Returns true if the player doesn't have the mutation or a conflicting one and it complies with the force typing. More...
 
void mutate_category (const std::string &mut_cat)
 Picks a random valid mutation in a category and mutate_towards() it. More...
 
bool mutate_towards (std::vector< trait_id > muts, int num_tries=INT_MAX)
 Mutates toward one of the given mutations, upgrading or removing conflicts if necessary. More...
 
bool mutate_towards (const trait_id &mut)
 Mutates toward the entered mutation, upgrading or removing conflicts if necessary. More...
 
void remove_mutation (const trait_id &mut, bool silent=false)
 Removes a mutation, downgrading to the previous level if possible. More...
 
std::map< trait_id, float > mutation_chances () const
 Calculate percentage chances for mutations. More...
 
bool has_child_flag (const trait_id &flag) const
 Returns true if the player has the entered mutation child flag. More...
 
void remove_child_flag (const trait_id &flag)
 Removes the mutation's child flag from the player's list. More...
 
void set_highest_cat_level ()
 Recalculates mutation_category_level[] values for the player. More...
 
std::string get_highest_category () const
 Returns the highest mutation category. More...
 
void drench_mut_calc ()
 Recalculates mutation drench protection for all bodyparts (ignored/good/neutral stats) More...
 
void build_mut_dependency_map (const trait_id &mut, std::unordered_map< trait_id, int > &dependency_map, int distance)
 Recursively traverses the mutation's prerequisites and replacements, building up a map. More...
 
bool is_category_allowed (const std::vector< std::string > &category) const
 Returns true if this category of mutation is allowed. More...
 
bool is_category_allowed (const std::string &category) const
 
bool is_weak_to_water () const
 
bool can_use_heal_item (const item &med) const
 Check for mutation disallowing the use of an healing item. More...
 
bool can_install_cbm_on_bp (const std::vector< bodypart_id > &bps) const
 
resistances mutation_armor (bodypart_id bp) const
 Returns resistances on a body part provided by mutations. More...
 
float mutation_armor (bodypart_id bp, damage_type dt) const
 
float mutation_armor (bodypart_id bp, const damage_unit &du) const
 
bool activate_bionic (bionic &bio, bool eff_only=false)
 Handles bionic activation effects of the entered bionic, returns if anything activated. More...
 
std::vector< bionic_idget_bionics () const
 
bionicget_bionic_state (const bionic_id &id)
 Get state of bionic with given id. More...
 
std::pair< int, int > amount_of_storage_bionics () const
 Returns amount of Storage CBMs in the corpse. More...
 
bool has_bionic (const bionic_id &b) const
 Returns true if the player has the entered bionic id. More...
 
bool has_active_bionic (const bionic_id &b) const
 Returns true if the player has the entered bionic id and it is powered on. More...
 
bool has_any_bionic () const
 Returns true if the player has any bionic. More...
 
bool can_fuel_bionic_with (const item &it) const
 Returns true if the character can fuel a bionic with the item. More...
 
std::vector< bionic_idget_bionic_fueled_with (const item &it) const
 Return bionic_id of bionics able to use it as fuel. More...
 
std::vector< bionic_idget_fueled_bionics () const
 Return bionic_id of fueled bionics. More...
 
bionic_id get_remote_fueled_bionic () const
 Returns bionic_id of first remote fueled bionic found. More...
 
bionic_id get_most_efficient_bionic (const std::vector< bionic_id > &bids) const
 Return bionic_id of bionic of most fuel efficient bionic. More...
 
std::vector< itype_idget_fuel_available (const bionic_id &bio) const
 Return list of available fuel for this bionic. More...
 
int get_fuel_type_available (const itype_id &fuel) const
 Return available space to store specified fuel. More...
 
int get_fuel_capacity (const itype_id &fuel) const
 Return available space to store specified fuel. More...
 
int get_total_fuel_capacity (const itype_id &fuel) const
 Return total space to store specified fuel. More...
 
void update_fuel_storage (const itype_id &fuel)
 Updates which bionic contain fuel and which is empty. More...
 
int get_mod_stat_from_bionic (const character_stat &Stat) const
 Get stat bonus from bionic. More...
 
void process_bionic (bionic &bio)
 Handles bionic effects over time of the entered bionic. More...
 
bool deactivate_bionic (bionic &bio, bool eff_only=false)
 Handles bionic deactivation effects of the entered bionic, returns if anything deactivated. More...
 
bool has_bionics () const
 Whether character has any bionics installed. More...
 
void clear_bionics ()
 Remove all bionics. More...
 
int get_used_bionics_slots (const bodypart_id &bp) const
 
int get_total_bionics_slots (const bodypart_id &bp) const
 
int get_free_bionics_slots (const bodypart_id &bp) const
 
bool has_enough_anesth (const itype *cbm, player &patient)
 Has enough anesthetic for surgery. More...
 
void introduce_into_anesthesia (const time_duration &duration, player &installer, bool needs_anesthesia)
 Handles process of introducing patient into anesthesia during Autodoc operations. More...
 
void remove_bionic (const bionic_id &b)
 Removes a bionic from my_bionics[]. More...
 
void add_bionic (const bionic_id &b)
 Adds a bionic to my_bionics[]. More...
 
float env_surgery_bonus (int radius)
 Calculate skill bonus from tiles in radius. More...
 
float bionics_adjusted_skill (const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
 Calculate skill for (un)installing bionics. More...
 
int bionics_pl_skill (const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
 Calculate non adjusted skill for (un)installing bionics. More...
 
bool can_install_bionics (const itype &type, player &installer, bool autodoc=false, int skill_level=-1)
 Is the installation possible. More...
 
std::map< bodypart_id, int > bionic_installation_issues (const bionic_id &bioid) const
 
bool install_bionics (const itype &type, player &installer, bool autodoc=false, int skill_level=-1)
 Initialize all the values needed to start the operation player_activity. More...
 
void perform_install (bionic_id bid, bionic_id upbid, int difficulty, int success, int pl_skill, const std::string &installer_name, const std::vector< trait_id > &trait_to_rem)
 Success or failure of installation happens here. More...
 
void do_damage_for_bionic_failure (int min_damage, int max_damage)
 
void bionics_install_failure (const std::string &installer, int difficulty, int success, float adjusted_skill)
 
bool can_uninstall_bionic (const bionic_id &b_id, player &installer, bool autodoc=false, int skill_level=-1)
 Is The uninstallation possible. More...
 
bool uninstall_bionic (const bionic_id &b_id, player &installer, bool autodoc=false, int skill_level=-1)
 Initialize all the values needed to start the operation player_activity. More...
 
void perform_uninstall (bionic_id bid, int difficulty, int success, const units::energy &power_lvl, int pl_skill)
 Succes or failure of removal happens here. More...
 
void bionics_uninstall_failure (int difficulty, int success, float adjusted_skill)
 When a player fails the surgery. More...
 
bool uninstall_bionic (const bionic &target_cbm, monster &installer, player &patient, float adjusted_skill)
 Used by monster to perform surgery. More...
 
void bionics_uninstall_failure (monster &installer, player &patient, int difficulty, int success, float adjusted_skill)
 When a monster fails the surgery. More...
 
bool burn_fuel (bionic &bio, bool start=false)
 Convert fuel to bionic power. More...
 
void passive_power_gen (bionic &bio)
 Passively produce power from PERPETUAL fuel. More...
 
itype_id find_remote_fuel (bool look_only=false)
 Find fuel used by remote powered bionic. More...
 
int consume_remote_fuel (int amount)
 Consume fuel used by remote powered bionic, return amount of request unfulfilled (0 if totally successful). More...
 
void reset_remote_fuel ()
 
void heat_emission (bionic &bio, int fuel_energy)
 Handle heat from exothermic power generation. More...
 
float get_effective_efficiency (bionic &bio, float fuel_efficiency)
 Applies modifier to fuel_efficiency and returns the resulting efficiency. More...
 
units::energy get_power_level () const
 
units::energy get_max_power_level () const
 
void mod_power_level (const units::energy &npower)
 
void mod_max_power_level (const units::energy &npower_max)
 
void set_power_level (const units::energy &npower)
 
void set_max_power_level (const units::energy &npower_max)
 
bool is_max_power () const
 
bool has_power () const
 
bool has_max_power () const
 
bool enough_power_for (const bionic_id &bid) const
 
void conduct_blood_analysis () const
 
bool is_worn (const item &thing) const
 
virtual bool invoke_item (item *, const tripoint &pt)
 Asks how to use the item (if it has more than one use_method) and uses it. More...
 
virtual bool invoke_item (item *, const std::string &, const tripoint &pt)
 As above, but with a pre-selected method. More...
 
virtual bool invoke_item (item *)
 As above two, but with position equal to current position. More...
 
virtual bool invoke_item (item *, const std::string &)
 
virtual bool dispose_item (item_location &&obj, const std::string &prompt=std::string())
 Drop, wear, stash or otherwise try to dispose of an item consuming appropriate moves. More...
 
bool has_enough_charges (const item &it, bool show_msg) const
 Has the item enough charges to invoke its use function? Also checks if UPS from this player is used instead of item charges. More...
 
bool consume_charges (item &used, int qty)
 Consume charges of a tool or comestible item, potentially destroying it in the process. More...
 
int item_handling_cost (const item &it, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
 Calculate (but do not deduct) the number of moves required when handling (e.g. More...
 
int item_store_cost (const item &it, const item &container, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
 Calculate (but do not deduct) the number of moves required when storing an item in a container. More...
 
int item_wear_cost (const item &it) const
 Calculate (but do not deduct) the number of moves required to wear an item. More...
 
int amount_worn (const itype_id &id) const
 Returns the amount of item ‘type’ that is currently worn. More...
 
std::vector< item_locationnearby (const std::function< bool(const item *, const item *)> &func, int radius=1) const
 Returns nearby items which match the provided predicate. More...
 
std::list< itemremove_worn_items_with (std::function< bool(item &)> filter)
 Similar to remove_items_with, but considers only worn items and not their content (item::contents is not checked). More...
 
iteminvlet_to_item (int invlet)
 Return the item pointer of the item with given invlet, return nullptr if the player does not have such an item with that invlet. More...
 
itemi_at (int position)
 
const itemi_at (int position) const
 
int get_item_position (const item *it) const
 Returns the item position (suitable for i_at or similar) of a specific item. More...
 
std::vector< item * > wielded_items ()
 Returns all equipped items that require a limb to be held. More...
 
std::vector< const item * > wielded_items () const
 
itemused_weapon ()
 Legacy code hack, don't use. More...
 
const itemused_weapon () const
 
itemprimary_weapon ()
 Legacy code hack, don't use. More...
 
const itemprimary_weapon () const
 
void set_primary_weapon (const item &new_weapon)
 Use this when primary weapon might not exist yet. More...
 
int i_add_to_container (const item &it, bool unloading)
 Try to find a container/s on character containing ammo of type it.typeId() and add charges until the container is full. More...
 
itemi_add (item it, bool should_stack=true)
 
item i_rem (int pos)
 Remove a specific item from player possession. More...
 
item i_rem (const item *it)
 Remove a specific item from player possession. More...
 
void i_rem_keep_contents (int idx)
 
bool i_add_or_drop (item &it, int qty=1)
 Sets invlet and adds to inventory if possible, drops otherwise, returns true if either succeeded. More...
 
std::bitset< std::numeric_limits< char >::max()> allocated_invlets () const
 Only use for UI things. More...
 
bool has_active_item (const itype_id &id) const
 Whether the player carries an active item of the given item type. More...
 
item remove_weapon ()
 
bool has_mission_item (int mission_id) const
 
void remove_mission_items (int mission_id)
 
int throw_range (const item &) const
 Maximum thrown range with a given item, taking all active effects into account. More...
 
bool unarmed_attack () const
 True if unarmed or wielding a weapon with the UNARMED_WEAPON flag. More...
 
int best_nearby_lifting_assist () const
 Checks for items, tools, and vehicles with the Lifting quality near the character returning the highest quality in range. More...
 
int best_nearby_lifting_assist (const tripoint &world_pos) const
 Alternate version if you need to specify a different orign point for nearby vehicle sources of lifting used for operations on distant objects (e.g. More...
 
std::vector< item * > inv_dump ()
 
units::mass weight_carried () const
 
units::volume volume_carried () const
 
units::mass weight_carried_reduced_by (const excluded_stacks &without) const
 
units::volume volume_carried_reduced_by (const excluded_stacks &without) const
 
units::mass weight_capacity () const override
 
units::volume volume_capacity () const
 
units::volume volume_capacity_reduced_by (const units::volume &mod, const excluded_stacks &without={}) const
 
bool can_pick_volume (const item &it) const
 
bool can_pick_volume (units::volume volume) const
 
bool can_pick_weight (const item &it, bool safe=true) const
 
bool can_pick_weight (units::mass weight, bool safe=true) const
 
bool can_use (const item &it, const item &context=item()) const
 Checks if character stats and skills meet minimum requirements for the item. More...
 
ret_val< bool > can_wear (const item &it, bool with_equip_change=false) const
 Check character capable of wearing an item. More...
 
std::optional< std::list< item >::iterator > wear_possessed (item &to_wear, bool interactive=true)
 Wear specified item. More...
 
std::optional< std::list< item >::iterator > wear_item (const item &to_wear, bool interactive=true)
 Wear a copy of specified item. More...
 
ret_val< bool > can_takeoff (const item &it, const std::list< item > *res=nullptr) const
 Check if character is capable of taking off given item. More...
 
bool takeoff (item &it, std::list< item > *res=nullptr)
 Take off an item. More...
 
bool is_armed () const
 Returns true if the character is wielding something. More...
 
ret_val< bool > can_wield (const item &it) const
 Check whether character is capable of wielding given item. More...
 
virtual bool wield (item &target)=0
 Removes currently wielded item (if any) and replaces it with the target item. More...
 
ret_val< bool > can_unwield (const item &it) const
 Check whether character is capable of unwielding given item. More...
 
bool unwield ()
 Removes currently wielded item (if any) More...
 
ret_val< bool > can_swap (const item &it) const
 Check player capable of swapping the side of a worn item. More...
 
void drop_invalid_inventory ()
 
std::list< item * > get_dependent_worn_items (const item &it) const
 Returns all items that must be taken off before taking off this item. More...
 
void drop (item_location loc, const tripoint &where)
 Drops an item to the specified location. More...
 
virtual void drop (const drop_locations &what, const tripoint &target, bool stash=false)
 
virtual bool has_artifact_with (art_effect_passive effect) const
 
bool is_wielding (const item &target) const
 
bool covered_with_flag (const std::string &flag, const body_part_set &parts) const
 
bool is_waterproof (const body_part_set &parts) const
 
int leak_level (const std::string &flag) const
 
bool can_reload (const item &it, const itype_id &ammo=itype_id()) const
 Whether a tool or gun is potentially reloadable (optionally considering a specific ammo) More...
 
int item_reload_cost (const item &it, const item &ammo, int qty) const
 Calculate (but do not deduct) the number of moves required to reload an item with specified quantity of ammo. More...
 
bool is_wearing (const item &itm) const
 Returns true if the player is wearing the item. More...
 
bool is_wearing (const itype_id &it) const
 Returns true if the player is wearing an item of this type. More...
 
bool is_wearing_on_bp (const itype_id &it, const bodypart_id &bp) const
 Returns true if the player is wearing the item on the given body part. More...
 
bool worn_with_flag (const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
 Returns true if the player is wearing an item with the given flag. More...
 
const itemitem_worn_with_flag (const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
 Returns the first worn item with a given flag. More...
 
std::vector< std::string > get_overlay_ids () const
 Returns a list of the IDs of overlays on this character, sorted from "lowest" to "highest". More...
 
int get_skill_level (const skill_id &ident) const
 
int get_skill_level (const skill_id &ident, const item &context) const
 
const SkillLevelMapget_all_skills () const
 
SkillLevelget_skill_level_object (const skill_id &ident)
 
const SkillLevelget_skill_level_object (const skill_id &ident) const
 
void set_skill_level (const skill_id &ident, int level)
 
void mod_skill_level (const skill_id &ident, int delta)
 
bool meets_skill_requirements (const std::map< skill_id, int > &req, const item &context=item()) const
 Checks whether the character's skills meet the required. More...
 
bool meets_skill_requirements (const construction &con) const
 Checks whether the character's skills meet the required. More...
 
bool meets_stat_requirements (const item &it) const
 Checks whether the character's stats meets the stats required by the item. More...
 
bool meets_requirements (const item &it, const item &context=item()) const
 Checks whether the character meets overall requirements to be able to use the item. More...
 
std::string enumerate_unmet_requirements (const item &it, const item &context=item()) const
 Returns a string of missed requirements (both stats and skills) More...
 
int rust_rate () const
 Returns the player's skill rust rate. More...
 
void practice (const skill_id &id, int amount, int cap=99, bool suppress_warning=false)
 This handles giving xp for a skill. More...
 
int read_speed (bool return_stat_effect=true) const
 Returns the player's reading speed. More...
 
time_point get_time_died () const
 return the calendar::turn the character expired More...
 
void set_time_died (const time_point &time)
 set the turn the turn the character died if not already done More...
 
void die (Creature *nkiller) override
 Empty function. More...
 
std::string get_name () const override
 
std::vector< std::string > get_grammatical_genders () const override
 
template<typename ... Args>
bool query_yn (const char *const msg, Args &&... args) const
 It is supposed to hide the query_yn to simplify player vs. More...
 
virtual bool query_yn (const std::string &msg) const =0
 
bool is_immune_field (const field_type_id &fid) const override
 Returns true if we are immune to the field type with the given fid. More...
 
bool is_elec_immune () const override
 Returns true is the player is protected from electric shocks. More...
 
bool is_immune_effect (const efftype_id &) const override
 Returns true if the player is immune to this kind of effect. More...
 
bool is_immune_damage (damage_type) const override
 Returns true if the player is immune to this kind of damage. More...
 
bool is_rad_immune () const
 Returns true if the player is protected from radiation. More...
 
bool is_throw_immune () const
 Returns true if the player is immune to throws. More...
 
bool has_nv ()
 Returns true if the player has some form of night vision. More...
 
float rest_quality () const
 Returns >0 if character is sitting/lying and relatively inactive. More...
 
float healing_rate (float at_rest_quality) const
 Average hit points healed per turn. More...
 
float healing_rate_medicine (float at_rest_quality, const bodypart_id &bp) const
 Average hit points healed per turn from healing effects. More...
 
float mutation_value (const std::string &val) const
 Goes over all mutations, gets min and max of a value with given name. More...
 
social_modifiers get_mutation_social_mods () const
 Goes over all mutations, returning the sum of the social modifiers. More...
 
nc_color basic_symbol_color () const override
 
nc_color symbol_color () const override
 
std::string extended_description () const override
 
void pick_name (bool bUseDefault=false)
 Returns a random name from NAMES_*. More...
 
std::vector< trait_idget_base_traits () const
 Get the idents of all base traits. More...
 
std::vector< trait_idget_mutations (bool include_hidden=true) const
 Get the idents of all traits/mutations. More...
 
const std::bitset< NUM_VISION_MODES > & get_vision_modes () const
 
void clear_skills ()
 Clear the skills map, setting all levels to 0. More...
 
void clear_mutations ()
 Empties the trait and mutations lists. More...
 
bool crossed_threshold () const
 Returns true if the player has crossed a mutation threshold Player can only cross one mutation threshold. More...
 
void add_addiction (add_type type, int strength)
 Adds an addiction to the player. More...
 
void rem_addiction (add_type type)
 Removes an addition from the player. More...
 
bool has_addiction (add_type type) const
 Returns true if the player has an addiction of the specified type. More...
 
int addiction_level (add_type type) const
 Returns the intensity of the specified addiction. More...
 
void start_hauling ()
 
void stop_hauling ()
 
bool is_hauling () const
 
bool has_item_with_flag (const std::string &flag, bool need_charges=false) const
 
std::vector< const item * > all_items_with_flag (const std::string &flag) const
 All items that have the given flag (item::has_flag). More...
 
bool has_charges (const itype_id &it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >) const
 
std::list< itemuse_amount (itype_id it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
bool use_charges_if_avail (const itype_id &it, int quantity)
 
std::list< itemuse_charges (const itype_id &what, int qty, const std::function< bool(const item &)> &filter=return_true< item >)
 
bool has_fire (int quantity) const
 
void use_fire (int quantity)
 
void assign_stashed_activity ()
 
bool check_outbounds_activity (const player_activity &act, bool check_only=false)
 
void assign_activity (const activity_id &type, int moves=calendar::INDEFINITELY_LONG, int index=-1, int pos=INT_MIN, const std::string &name="")
 Legacy activity assignment, does not work for any activites using the new activity_actor class and may cause issues with resuming. More...
 
void assign_activity (const player_activity &act, bool allow_resume=true)
 Assigns activity to player, possibly resuming old activity if it's similar enough. More...
 
bool has_activity (const activity_id &type) const
 Check if player currently has a given activity. More...
 
bool has_activity (const std::vector< activity_id > &types) const
 Check if player currently has any of the given activities. More...
 
void resume_backlog_activity ()
 
void cancel_activity ()
 
void cancel_stashed_activity ()
 
player_activity get_stashed_activity () const
 
void set_stashed_activity (const player_activity &act, const player_activity &act_back=player_activity())
 
bool has_stashed_activity () const
 
void initialize_stomach_contents ()
 
float metabolic_rate_base () const
 Stable base metabolic rate due to traits. More...
 
float metabolic_rate () const
 Current metabolic rate due to traits, hunger, speed, etc. More...
 
std::string get_weight_string () const
 
int get_max_healthy () const
 
float bmi () const
 
int bmr () const
 
void reset_chargen_attributes ()
 
int base_age () const
 
void set_base_age (int age)
 
void mod_base_age (int mod)
 
int age () const
 
std::string age_string () const
 
int base_height () const
 
void set_base_height (int height)
 
void mod_base_height (int mod)
 
std::string height_string () const
 
int height () const
 
units::mass bodyweight () const
 
units::mass bionics_weight () const
 
int get_armor_bash (bodypart_id bp) const override
 Returns overall bashing resistance for the body_part. More...
 
int get_armor_cut (bodypart_id bp) const override
 Returns overall cutting resistance for the body_part. More...
 
int get_armor_bullet (bodypart_id bp) const override
 Returns overall bullet resistance for the body_part. More...
 
int get_armor_bash_base (bodypart_id bp) const override
 Returns bashing resistance from the creature and armor only. More...
 
int get_armor_cut_base (bodypart_id bp) const override
 Returns cutting resistance from the creature and armor only. More...
 
int get_armor_bullet_base (bodypart_id bp) const override
 Returns cutting resistance from the creature and armor only. More...
 
int get_env_resist (bodypart_id bp) const override
 Returns overall env_resist on a body_part. More...
 
int get_armor_acid (bodypart_id bp) const
 Returns overall acid resistance for the body part. More...
 
int get_armor_type (damage_type dt, bodypart_id bp) const override
 Returns overall resistance to given type on the bod part. More...
 
std::map< bodypart_id, int > get_all_armor_type (damage_type dt, const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
 
int get_stim () const
 
void set_stim (int new_stim)
 
void mod_stim (int mod)
 
int get_rad () const
 
void set_rad (int new_rad)
 
void mod_rad (int mod)
 
int get_stamina () const
 
int get_stamina_max () const
 
void set_stamina (int new_stamina)
 
void mod_stamina (int mod)
 
void burn_move_stamina (int moves)
 
float stamina_move_cost_modifier () const
 
void update_stamina (int turns)
 Regenerates stamina. More...
 
void on_item_wear (const item &it)
 Called when an item is worn. More...
 
void on_item_takeoff (const item &it)
 Called when an item is taken off. More...
 
void on_worn_item_washed (const item &it)
 Called when an item is washed. More...
 
void on_effect_int_change (const efftype_id &effect_type, int intensity, const bodypart_str_id &bp) override
 Called when effect intensity has been changed. More...
 
void on_mutation_gain (const trait_id &mid)
 Called when a mutation is gained. More...
 
void on_mutation_loss (const trait_id &mid)
 Called when a mutation is lost. More...
 
void on_stat_change (const std::string &stat, int value) override
 Called when a stat is changed. More...
 
void on_worn_item_transform (const item &old_it, const item &new_it)
 Called when a worn item is transformed. More...
 
void wake_up ()
 Removes "sleep" and "lying_down". More...
 
int get_shout_volume () const
 
void shout (std::string msg="", bool order=false)
 
void vomit ()
 Handles Character vomiting effects. More...
 
void healed_bp (int bp, int amount)
 
int adjust_for_focus (int amount) const
 
void update_type_of_scent (bool init=false)
 
void update_type_of_scent (const trait_id &mut, bool gain=true)
 
void set_type_of_scent (const scenttype_id &id)
 
scenttype_id get_type_of_scent () const
 
void restore_scent ()
 restore scent after masked_scent effect run out or is removed by water More...
 
void mod_painkiller (int npkill)
 Modifies intensity of painkillers
More...
 
void set_painkiller (int npkill)
 Sets intensity of painkillers
More...
 
int get_painkiller () const
 Returns intensity of painkillers
More...
 
void react_to_felt_pain (int intensity)
 
void mod_pain (int npain) override
 Modifies a pain value by player traits before passing it to Creature::mod_pain() More...
 
void set_pain (int npain) override
 Sets new intensity of pain an reacts to it. More...
 
int get_perceived_pain () const override
 Returns perceived pain (reduced with painkillers) More...
 
void spores ()
 
void blossoms ()
 
void rooted_message () const
 Handles rooting effects. More...
 
void rooted ()
 
void fall_asleep ()
 Adds "sleep" to the player. More...
 
void fall_asleep (const time_duration &duration)
 
std::string is_snuggling () const
 Checks to see if the player is using floor items to keep warm, and return the name of one such item if so. More...
 
float power_rating () const override
 Returns an approximation of the creature's strength. More...
 
float speed_rating () const override
 Returns an approximate number of tiles this creature can travel per turn. More...
 
itemitem_with_best_of_quality (const quality_id &qid)
 Returns the item in the player's inventory with the highest of the specified quality. More...
 
bool sees_with_infrared (const Creature &critter) const
 Check whether the this player can see the other creature with infrared. More...
 
void place_corpse ()
 
void place_corpse (const tripoint_abs_omt &om_target)
 
int run_cost (int base_cost, bool diag=false) const
 Returns the player's modified base movement cost. More...
 
const pathfinding_settingsget_pathfinding_settings () const override
 Returns settings for pathfinding. More...
 
std::set< tripointget_path_avoid () const override
 Returns a set of points we do not want to path through. More...
 
std::vector< Creature * > get_hostile_creatures (int range) const
 Get all hostile creatures currently visible to this player. More...
 
std::vector< Creature * > get_visible_creatures (int range) const
 Returns all creatures that this player can see and that are in the given range. More...
 
std::string visible_mutations (int visibility_cap) const
 Returns an enumeration of visible mutations with colors. More...
 
player_activity get_destination_activity () const
 
void set_destination_activity (const player_activity &new_destination_activity)
 
void clear_destination_activity ()
 
std::map< bodypart_id, int > warmth (const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
 Returns warmth provided by armor, etc. More...
 
bool can_use_floor_warmth () const
 Can the player lie down and cover self with blankets etc. More...
 
int floor_warmth (const tripoint &pos) const
 Final warmth from the floor. More...
 
int bodytemp_modifier_traits (bool overheated) const
 Correction factor of the body temperature due to traits and mutations. More...
 
int bodytemp_modifier_traits_floor () const
 Correction factor of the body temperature due to traits and mutations for player lying on the floor. More...
 
int temp_corrected_by_climate_control (int temperature) const
 Value of the body temperature corrected by climate control. More...
 
bool in_sleep_state () const override
 
void update_vitamins (const vitamin_id &vit)
 Set vitamin deficiency/excess disease states dependent upon current vitamin levels. More...
 
int vitamin_get (const vitamin_id &vit) const
 Check current level of a vitamin. More...
 
bool vitamin_set (const vitamin_id &vit, int qty)
 Sets level of a vitamin or returns false if id given in vit does not exist. More...
 
int vitamin_mod (const vitamin_id &vit, int qty, bool capped=true)
 Add or subtract vitamins from character storage pools. More...
 
void vitamins_mod (const std::map< vitamin_id, int > &, bool capped=true)
 
time_duration vitamin_rate (const vitamin_id &vit) const
 Get vitamin usage rate (minutes per unit) accounting for bionics, mutations and effects. More...
 
int nutrition_for (const item &comest) const
 Handles the nutrition value for a comestible. More...
 
ret_val< edible_ratingcan_eat (const item &food) const
 Can the food be [theoretically] eaten no matter the consequen ces? More...
 
ret_val< edible_ratingwill_eat (const item &food, bool interactive=false) const
 Same as can_eat, but takes consequences into account. More...
 
bool can_feed_furnace_with (const item &it) const
 Determine character's capability of recharging their CBMs. More...
 
rechargeable_cbm get_cbm_rechargeable_with (const item &it) const
 
int get_acquirable_energy (const item &it, rechargeable_cbm cbm) const
 
int get_acquirable_energy (const item &it) const
 
bool feed_furnace_with (item &it)
 Recharge CBMs whenever possible. More...
 
bool fuel_bionic_with (item &it)
 
void modify_stimulation (const islot_comestible &comest)
 Used to apply stimulation modifications from food and medication. More...
 
void modify_fatigue (const islot_comestible &comest)
 Used to apply fatigue modifications from food and medication. More...
 
void modify_radiation (const islot_comestible &comest)
 Used to apply radiation from food and medication. More...
 
void modify_addiction (const islot_comestible &comest)
 Used to apply addiction modifications from food and medication. More...
 
void modify_health (const islot_comestible &comest)
 Used to apply health modifications from food and medication. More...
 
bool consume_effects (item &food)
 Handles the effects of consuming an item. More...
 
bool can_consume (const item &it) const
 Check character's capability of consumption overall. More...
 
bool can_estimate_rot () const
 True if the character has enough skill (in cooking or survival) to estimate time to rot. More...
 
bool can_consume_as_is (const item &it) const
 Check whether character can consume this very item. More...
 
bool can_consume_for_bionic (const item &it) const
 
itemget_consumable_from (item &it) const
 Returns a reference to the item itself (if it's consumable), the first of its contents (if it's consumable) or null item otherwise. More...
 
void consume (item_location loc)
 Consume item (food, fuel, medicine, ...) at given location loc . More...
 
bool consume_item (item &target)
 Consume given item (food, fuel, medicine, ...). More...
 
bool consume_med (item &target)
 Consume an item as medication. More...
 
bool eat (item &food, bool force=false)
 Used for eating entered comestible, returns true if comestible is successfully eaten. More...
 
std::pair< nutrients, nutrientscompute_nutrient_range (const item &, const recipe_id &, const cata::flat_set< std::string > &extra_flags={}) const
 Get calorie & vitamin contents for a comestible, taking into account character traits. More...
 
std::pair< nutrients, nutrientscompute_nutrient_range (const itype_id &, const cata::flat_set< std::string > &extra_flags={}) const
 Same, but across arbitrary recipes. More...
 
morale_type allergy_type (const item &food) const
 Returns allergy type or MORALE_NULL if not allergic for this character. More...
 
nutrients compute_effective_nutrients (const item &) const
 
bool wearing_something_on (const bodypart_id &bp) const
 Returns true if the character is wearing something on the entered body part. More...
 
bool is_wearing_helmet () const
 Returns true if the character is wearing something occupying the helmet slot. More...
 
int head_cloth_encumbrance () const
 Returns the total encumbrance of all SKINTIGHT and HELMET_COMPAT items coveringi the head. More...
 
double armwear_factor () const
 Same as footwear factor, but for arms. More...
 
int shoe_type_count (const itype_id &it) const
 Returns 1 if the player is wearing an item of that count on one foot, 2 if on both, and zero if on neither. More...
 
double footwear_factor () const
 Returns 1 if the player is wearing something on both feet, .5 if on one, and 0 if on neither. More...
 
bool is_wearing_shoes (const side &which_side=side::BOTH) const
 Returns true if the player is wearing something on their feet that is not SKINTIGHT. More...
 
bool change_side (item &it, bool interactive=true)
 Swap side on which item is worn; returns false on fail. More...
 
bool change_side (item_location &loc, bool interactive=true)
 
bool get_check_encumbrance () const
 
void set_check_encumbrance (bool new_check)
 
void update_morale ()
 Ticks down morale counters and removes them. More...
 
void apply_persistent_morale ()
 Ensures persistent morale effects are up-to-date. More...
 
void modify_morale (item &food, int nutr=0)
 Used to apply morale modifications from food and medication. More...
 
int get_morale_level () const
 
void add_morale (const morale_type &type, int bonus, int max_bonus=0, const time_duration &duration=1_hours, const time_duration &decay_start=30_minutes, bool capped=false, const itype *item_type=nullptr)
 
bool has_morale (const morale_type &type) const
 
int get_morale (const morale_type &type) const
 
void rem_morale (const morale_type &type)
 
void clear_morale ()
 
bool has_morale_to_read () const
 
bool has_morale_to_craft () const
 
const inventorycrafting_inventory (bool clear_path)
 
const inventorycrafting_inventory (const tripoint &src_pos=tripoint_zero, int radius=PICKUP_RANGE, bool clear_path=true)
 
void invalidate_crafting_inventory ()
 
const recipe_subsetget_learned_recipes () const
 Returns all known recipes. More...
 
bool knows_recipe (const recipe *rec) const
 
void learn_recipe (const recipe *rec)
 
bool can_learn_by_disassembly (const recipe &rec) const
 
bool check_and_recover_morale ()
 Checks permanent morale for consistency and recovers it when an inconsistency is found. More...
 
std::pair< int, int > fun_for (const item &comest) const
 Handles the enjoyability value for a comestible. More...
 
void suffer ()
 Handles a large number of timers decrementing and other randomized effects. More...
 
bool irradiate (float rads, bool bypass=false)
 Handles mitigation and application of radiation. More...
 
void mend (int rate_multiplier)
 Handles the chance for broken limbs to spontaneously heal to 1 HP. More...
 
void sound_hallu ()
 Creates an auditory hallucination. More...
 
void drench (int saturation, const body_part_set &flags, bool ignore_waterproof)
 Drenches the player with water, saturation is the percent gotten wet. More...
 
void apply_wetness_morale (int temperature)
 Recalculates morale penalty/bonus from wetness based on mutations, equipment and temperature. More...
 
std::vector< std::string > short_description_parts () const
 
std::string short_description () const
 
int print_info (const catacurses::window &w, int vStart, int vLines, int column) const override
 Write information about this creature. More...
 
bool can_hear (const tripoint &source, int volume) const
 
float hearing_ability () const
 
bool knows_trap (const tripoint &pos) const
 
void add_known_trap (const tripoint &pos, const trap &t)
 
bool avoid_trap (const tripoint &pos, const trap &tr) const override
 Called when character triggers a trap, returns true if they don't set it off. More...
 
nc_color bodytemp_color (int bp) const
 Define color for displaying the body temperature. More...
 
bool sees (const tripoint &t, bool is_player=false, int range_mod=0) const override
 
bool sees (const Creature &critter) const override
 The functions check whether this creature can see the target. More...
 
Attitude attitude_to (const Creature &other) const override
 Attitude (of this creature) towards another creature. More...
 
int get_lowest_hp () const
 
bool has_weapon () const override
 
void shift_destination (point shift)
 
void set_destination (const std::vector< tripoint > &route, const player_activity &new_destination_activity=player_activity())
 
void clear_destination ()
 
bool has_distant_destination () const
 
bool is_auto_moving () const
 
bool has_destination () const
 
bool has_destination_activity () const
 
void start_destination_activity ()
 
std::vector< tripoint > & get_auto_move_route ()
 
action_id get_next_auto_move_direction ()
 
bool defer_move (const tripoint &next)
 
std::map< bodypart_id, float > bodypart_exposure ()
 Map body parts to their total exposure, from 0.0 (fully covered) to 1.0 (buck naked). More...
 
void set_underwater (bool x) override
 
void clear_npc_ai_info_cache (npc_ai_info key) const
 
void set_npc_ai_info_cache (npc_ai_info key, double val) const
 
std::optional< double > get_npc_ai_info_cache (npc_ai_info key) const
 
safe_reference< Characterget_safe_reference ()
 
bool pour_into (item &container, item &liquid)
 Try to pour the given liquid into the given container/vehicle. More...
 
bool pour_into (vehicle &veh, item &liquid)
 
- Public Member Functions inherited from Creature
virtual ~Creature ()
 
virtual bool is_player () const
 
virtual bool is_avatar () const
 
virtual bool is_npc () const
 
virtual bool is_monster () const
 
virtual monsteras_monster ()
 
virtual const monsteras_monster () const
 
virtual npcas_npc ()
 
virtual const npcas_npc () const
 
virtual playeras_player ()
 
virtual const playeras_player () const
 
virtual avataras_avatar ()
 
virtual const avataras_avatar () const
 
virtual bool is_fake () const
 Returns true for non-real Creatures used temporarily; i.e. More...
 
virtual void set_fake (bool fake_value)
 Sets a Creature's fake boolean. More...
 
virtual void bleed () const
 Adds an appropriate blood splatter. More...
 
Creatureauto_find_hostile_target (int range, int &boo_hoo, int area=0)
 For fake-players (turrets, mounted turrets) this functions chooses a target. More...
 
double ranged_target_size () const
 Size of the target this creature presents to ranged weapons. More...
 
void knock_back_from (const tripoint &p)
 
int size_melee_penalty () const
 
virtual int deal_melee_attack (Creature *source, int hitroll)
 
virtual void deal_melee_hit (Creature *source, int hit_spread, bool critical_hit, const damage_instance &dam, dealt_damage_instance &dealt_dam)
 
virtual void deal_projectile_attack (Creature *source, dealt_projectile_attack &attack)
 Attempts to harm a creature with a projectile. More...
 
virtual void deal_damage_handle_type (const damage_unit &du, bodypart_id bp, int &damage, int &pain)
 
virtual bool digging () const
 
virtual bool is_underwater () const
 
virtual bool is_hallucination () const =0
 
bool is_dangerous_fields (const field &fld) const
 Returns true if there is a field in the field set that is dangerous to us. More...
 
bool is_dangerous_field (const field_entry &entry) const
 Returns true if the given field entry is dangerous to us. More...
 
void check_dead_state ()
 This function checks the creatures is_dead_state and (if true) calls die. More...
 
void add_effect (const effect &eff, bool force=false, bool deferred=false)
 
virtual void add_effect (const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false)
 Adds or modifies an effect. More...
 
void add_effect (const efftype_id &eff_id, const time_duration &dur, body_part bp=num_bp, int intensity=0, bool force=false, bool deferred=false)
 
bool add_env_effect (const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp=num_bp, int intensity=1, bool force=false)
 Gives chance to save via environmental resist, returns false if resistance was successful. More...
 
bool add_env_effect (const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp, bool REMOVED, int intensity=1, bool force=false)=delete
 
bool remove_effect (const efftype_id &eff_id, body_part bp=num_bp)
 Removes a listed effect. More...
 
virtual bool remove_effect (const efftype_id &eff_id, const bodypart_str_id &bp)
 
void clear_effects ()
 Remove all effects. More...
 
bool has_effect (const efftype_id &eff_id, body_part bp=num_bp) const
 Check if creature has the matching effect. More...
 
bool has_effect (const efftype_id &eff_id, const bodypart_str_id &bp) const
 
bool has_effect_with_flag (const std::string &flag, body_part bp=num_bp) const
 Check if creature has any effect with the given flag. More...
 
const effectget_effect (const efftype_id &eff_id, body_part bp=num_bp) const
 Return the effect that matches the given arguments exactly. More...
 
effectget_effect (const efftype_id &eff_id, body_part bp=num_bp)
 
std::vector< const effect * > get_all_effects_of_type (const efftype_id &eff_id) const
 Returns pointers to all effects matching given type. More...
 
std::vector< effect * > get_all_effects_of_type (const efftype_id &eff_id)
 
time_duration get_effect_dur (const efftype_id &eff_id, body_part bp=num_bp) const
 Returns the duration of the matching effect. More...
 
int get_effect_int (const efftype_id &eff_id, body_part bp=num_bp) const
 Returns the intensity of the matching effect. More...
 
bool resists_effect (const effect &e) const
 Returns true if the creature resists an effect. More...
 
void set_value (const std::string &key, const std::string &value)
 
void remove_value (const std::string &key)
 
std::string get_value (const std::string &key) const
 
void process_effects ()
 Processes through all the effects on the Creature. More...
 
virtual void mod_pain_noresist (int npain)
 
virtual int get_pain () const
 
int get_moves () const
 
void mod_moves (int nmoves)
 
void set_moves (int nmoves)
 
virtual Creatureget_killer () const
 
virtual int get_num_blocks () const
 
virtual int get_num_dodges () const
 
virtual int get_num_blocks_bonus () const
 
virtual int get_num_dodges_bonus () const
 
virtual int get_num_dodges_base () const
 
virtual int get_armor_bash_bonus () const
 
virtual int get_armor_cut_bonus () const
 
virtual int get_armor_bullet_bonus () const
 
virtual float get_hit () const
 
virtual int get_hp (const bodypart_id &bp) const
 
virtual int get_hp () const
 
virtual int get_hp_max (const bodypart_id &bp) const
 
virtual int get_hp_max () const
 
virtual bool has_flag (const m_flag) const
 
anatomy_id get_anatomy () const
 
void set_anatomy (anatomy_id anat)
 
bodypart_id get_random_body_part (bool main=false) const
 
std::vector< bodypart_idget_all_body_parts (bool only_main=false) const
 Returns body parts this creature have. More...
 
const std::map< bodypart_str_id, bodypart > & get_body () const
 
void set_body ()
 
bodypartget_part (const bodypart_id &id)
 
const bodypartget_part (const bodypart_id &id) const
 
int get_part_hp_cur (const bodypart_id &id) const
 
int get_part_hp_max (const bodypart_id &id) const
 
int get_part_healed_total (const bodypart_id &id) const
 
void set_part_hp_cur (const bodypart_id &id, int set)
 
void set_part_hp_max (const bodypart_id &id, int set)
 
void set_part_healed_total (const bodypart_id &id, int set)
 
void mod_part_hp_cur (const bodypart_id &id, int mod)
 
void mod_part_hp_max (const bodypart_id &id, int mod)
 
void mod_part_healed_total (const bodypart_id &id, int mod)
 
void set_all_parts_hp_cur (int set)
 
void set_all_parts_hp_to_max ()
 
virtual int get_speed_base () const
 
virtual int get_speed_bonus () const
 
virtual float get_speed_mult () const
 
virtual int get_block_bonus () const
 
virtual float get_dodge_bonus () const
 
virtual float get_hit_bonus () const
 
virtual void set_num_blocks_bonus (int nblocks)
 
virtual void mod_num_dodges_bonus (int ndodges)
 
virtual void set_armor_bash_bonus (int nbasharm)
 
virtual void set_armor_cut_bonus (int ncutarm)
 
virtual void set_armor_bullet_bonus (int nbulletarm)
 
virtual void set_speed_base (int nspeed)
 
virtual void set_speed_bonus (int nspeed)
 
virtual void set_speed_mult (float nspeed)
 
virtual void set_block_bonus (int nblock)
 
virtual void mod_speed_bonus (int nspeed)
 
virtual void mod_speed_mult (float nspeed)
 
virtual void mod_block_bonus (int nblock)
 
virtual void set_dodge_bonus (float ndodge)
 
virtual void set_hit_bonus (float nhit)
 
virtual void mod_dodge_bonus (float ndodge)
 
virtual void mod_hit_bonus (float nhit)
 
void draw (const catacurses::window &w, point origin, bool inverted) const
 
void draw (const catacurses::window &w, const tripoint &origin, bool inverted) const
 
void describe_infrared (std::vector< std::string > &buf) const
 Describe this creature as seen by the avatar via infrared vision. More...
 
void describe_specials (std::vector< std::string > &buf) const
 Describe this creature as detected by the avatar's special senses. More...
 
virtual void add_msg_if_player (const std::string &) const
 
virtual void add_msg_if_player (const game_message_params &, const std::string &) const
 
void add_msg_if_player (const translation &) const
 
void add_msg_if_player (const game_message_params &, const translation &) const
 
template<typename ... Args>
void add_msg_if_player (const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const translation &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const game_message_params &params, const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const game_message_params &params, const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const game_message_params &params, const translation &msg, Args &&... args) const
 
virtual void add_msg_if_npc (const std::string &) const
 
virtual void add_msg_if_npc (const game_message_params &, const std::string &) const
 
void add_msg_if_npc (const translation &) const
 
void add_msg_if_npc (const game_message_params &, const translation &) const
 
template<typename ... Args>
void add_msg_if_npc (const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const translation &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const game_message_params &params, const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const game_message_params &params, const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const game_message_params &params, const translation &msg, Args &&... args) const
 
virtual void add_msg_player_or_npc (const std::string &, const std::string &) const
 
virtual void add_msg_player_or_npc (const game_message_params &, const std::string &, const std::string &) const
 
void add_msg_player_or_npc (const translation &, const translation &) const
 
void add_msg_player_or_npc (const game_message_params &, const translation &, const translation &) const
 
template<typename ... Args>
void add_msg_player_or_npc (const char *const player_msg, const char *const npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const std::string &player_msg, const std::string &npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const translation &player_msg, const translation &npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const game_message_params &params, const char *const player_msg, const char *const npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const game_message_params &params, const std::string &player_msg, const std::string &npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const game_message_params &params, const translation &player_msg, const translation &npc_msg, Args &&... args) const
 
virtual void add_msg_player_or_say (const std::string &, const std::string &) const
 
virtual void add_msg_player_or_say (const game_message_params &, const std::string &, const std::string &) const
 
void add_msg_player_or_say (const translation &, const translation &) const
 
void add_msg_player_or_say (const game_message_params &, const translation &, const translation &) const
 
template<typename ... Args>
void add_msg_player_or_say (const char *const player_msg, const char *const npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const std::string &player_msg, const std::string &npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const translation &player_msg, const translation &npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const game_message_params &params, const char *const player_msg, const char *const npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const game_message_params &params, const std::string &player_msg, const std::string &npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const game_message_params &params, const translation &player_msg, const translation &npc_speech, Args &&... args) const
 
virtual bool is_symbol_highlighted () const
 
effects_map get_all_effects () const
 
body_part select_body_part (Creature *source, int hit_roll) const
 
std::string replace_with_npc_name (std::string input) const
 This function replaces the "<npcname>" substring with the disp_name of this creature. More...
 
- Public Member Functions inherited from visitable< Character >
VisitResponse visit_items (const std::function< VisitResponse(item *, item *)> &func)
 Traverses this object and any child items contained using a visitor pattern. More...
 
VisitResponse visit_items (const std::function< VisitResponse(const item *, const item *)> &func) const
 
VisitResponse visit_items (const std::function< VisitResponse(item *)> &func)
 Lightweight version which provides only the current node. More...
 
VisitResponse visit_items (const std::function< VisitResponse(const item *)> &func) const
 
itemfind_parent (const item &it)
 Determine the immediate parent container (if any) for an item. More...
 
const itemfind_parent (const item &it) const
 
std::vector< item * > parents (const item &it)
 Returns vector of parent containers (if any) starting with the innermost. More...
 
std::vector< const item * > parents (const item &it) const
 
bool has_item (const item &it) const
 Returns true if this visitable instance contains the item. More...
 
bool has_item_with (const std::function< bool(const item &)> &filter) const
 Returns true if any item (including those within a container) matches the filter. More...
 
bool has_quality (const quality_id &qual, int level=1, int qty=1) const
 Returns true if instance has amount (or more) items of at least quality level. More...
 
int max_quality (const quality_id &qual) const
 Return maximum tool quality level provided by instance or INT_MIN if not found. More...
 
int charges_of (const itype_id &what, int limit=INT_MAX, const std::function< bool(const item &)> &filter=return_true< item >, std::function< void(int)> visitor=nullptr) const
 Count maximum available charges from this instance and any contained items. More...
 
int amount_of (const itype_id &what, bool pseudo=true, int limit=INT_MAX, const std::function< bool(const item &)> &filter=return_true< item >) const
 Count items matching id including both this instance and any contained items. More...
 
bool has_amount (const itype_id &what, int qty, bool pseudo=true, const std::function< bool(const item &)> &filter=return_true< item >) const
 Check instance provides at least qty of an item (. More...
 
std::vector< item * > items_with (const std::function< bool(const item &)> &filter)
 Returns all items (including those within a container) matching the filter. More...
 
std::vector< const item * > items_with (const std::function< bool(const item &)> &filter) const
 
std::list< itemremove_items_with (const std::function< bool(const item &)> &filter, int count=INT_MAX)
 Removes items contained by this instance which match the filter. More...
 
item remove_item (item &it)
 Removes and returns the item which must be contained by this instance. More...
 

Static Public Member Functions

static hp_part bp_to_hp (body_part bp)
 Converts a body_part to an hp_part. More...
 
static body_part hp_to_bp (hp_part hpart)
 Converts an hp_part to a body_part. More...
 
static int worn_position_to_index (int position)
 
static int floor_bedding_warmth (const tripoint &pos)
 Warmth from terrain, furniture, vehicle furniture and traps. More...
 
static int floor_item_warmth (const tripoint &pos)
 Warmth from clothing on the floor. More...
 
- Static Public Member Functions inherited from Creature
static std::string attitude_raw_string (Attitude att)
 Simplified attitude string for unlocalized needs. More...
 
static const std::pair< translation, nc_color > & get_attitude_ui_data (Attitude att)
 Creature Attitude as String and color. More...
 
static void load_hit_range (const JsonObject &)
 
static void reset_hit_range ()
 

Public Attributes

bool death_drops = true
 
bool controlling_vehicle = false
 
int str_max = 0
 
int dex_max = 0
 
int int_max = 0
 
int per_max = 0
 
int str_cur = 0
 
int dex_cur = 0
 
int int_cur = 0
 
int per_cur = 0
 
int blocks_left = 0
 
int dodges_left = 0
 
double recoil = MAX_RECOIL
 
profession_id prof
 
std::string custom_profession
 
bool reach_attacking = false
 
pimpl< known_magicmagic
 
std::string name
 
bool male = true
 
std::list< itemworn
 
std::array< int, num_hp_partsdamage_bandaged
 
std::array< int, num_hp_partsdamage_disinfected
 
bool nv_cached = false
 
bool in_vehicle = false
 
bool hauling = false
 
player_activity stashed_outbounds_activity
 
player_activity stashed_outbounds_backlog
 
player_activity activity
 
std::list< player_activitybacklog
 
std::optional< tripointdestination_point
 
inventory inv
 
itype_id last_item
 
int scent = 0
 
pimpl< bionic_collectionmy_bionics
 
pimpl< character_martial_artsmartial_arts_data
 
stomach_contents stomach
 
pimpl< consumption_history_tconsumption_history
 
int oxygen = 0
 
int tank_plut = 0
 
int reactor_plut = 0
 
int slow_rad = 0
 
int focus_pool = 0
 
int cash = 0
 
std::set< character_idfollower_ids
 
item_location ammo_location
 
std::set< tripoint_abs_omtcamps
 
time_point cached_time
 
std::vector< addictionaddictions
 
shared_ptr_fast< monstermounted_creature
 
int mounted_creature_id = 0
 
int activity_vehicle_part_index = -1
 
std::array< int, num_hp_partshealed_total
 
std::map< std::string, int > mutation_category_level
 
std::vector< tripoint_abs_omtomt_path
 Route for overmap scale traveling. More...
 
mutation_collection my_mutations
 Traits / mutations of the character. More...
 
time_point last_sleep_check = calendar::turn_zero
 
bool bio_soporific_powered_at_last_sleep_check = false
 
std::array< int, num_bptemp_cur
 
std::array< int, num_bpfrostbite_timer
 
std::array< int, num_bptemp_conv
 
std::array< int, num_bpbody_wetness
 
std::array< int, num_bpdrench_capacity
 
time_point next_climate_control_check
 
bool last_climate_control_ret = false
 
- Public Attributes inherited from Creature
FacingDirection facing = FD_RIGHT
 return the direction the creature is facing, for sdl horizontal flip More...
 
int moves = 0
 

Static Public Attributes

static const std::vector< material_idfleshy = { material_id( "flesh" ), material_id( "hflesh" ) }
 
- Static Public Attributes inherited from Creature
static const std::map< std::string, m_sizesize_map
 
static const std::set< material_idcmat_flesh
 
static const std::set< material_idcmat_fleshnveg
 
static const std::set< material_idcmat_flammable
 
static const std::set< material_idcmat_flameres
 
static std::vector< int > dispersion_for_even_chance_of_good_hit = default_dispersion_for_ecogh
 

Protected Member Functions

void do_skill_rust ()
 
void apply_mods (const trait_id &mut, bool add_remove)
 Applies stat mods to character. More...
 
char_encumbrance_data calc_encumbrance () const
 Recalculate encumbrance for all body parts. More...
 
char_encumbrance_data calc_encumbrance (const item &new_item) const
 Recalculate encumbrance for all body parts as if new_item was also worn. More...
 
void mut_cbm_encumb (char_encumbrance_data &vals) const
 Applies encumbrance from mutations and bionics only. More...
 
std::list< item >::iterator position_to_wear_new_item (const item &new_item)
 Return the position in the worn list where new_item would be put by default. More...
 
void item_encumb (char_encumbrance_data &vals, const item &new_item) const
 Applies encumbrance from items only If new_item is not null, then calculate under the asumption that it is added to existing work items. More...
 
void on_damage_of_type (int adjusted_damage, damage_type type, const bodypart_id &bp) override
 
 Character ()
 
 Character (Character &&)
 
Characteroperator= (Character &&)
 
void store (JsonOut &json) const
 Load variables from json into object. More...
 
void load (const JsonObject &data)
 Gather variables for saving. More...
 
- Protected Member Functions inherited from Creature
void set_killer (Creature *killer)
 
 Creature ()
 
 Creature (const Creature &)=default
 
 Creature (Creature &&)=default
 
Creatureoperator= (const Creature &)=default
 
Creatureoperator= (Creature &&)=default
 
void store (JsonOut &jsout) const
 These two functions are responsible for storing and loading the members of this class to/from json data. More...
 
void load (const JsonObject &jsin)
 

Protected Attributes

std::array< std::array< int, NUM_WATER_TOLERANCE >, num_bpmut_drench
 
tripoint position
 
int str_bonus = 0
 Bonuses to stats, calculated each turn. More...
 
int dex_bonus = 0
 
int per_bonus = 0
 
int int_bonus = 0
 
int healthy = 0
 How healthy the character is. More...
 
int healthy_mod = 0
 
int init_age = 25
 age in years at character creation More...
 
int init_height = 175
 height at character creation More...
 
m_size size_class = MS_MEDIUM
 Size class of character. More...
 
trap_map known_traps
 
pimpl< char_encumbrance_dataencumbrance_cache
 
std::unordered_set< trait_idmy_traits
 Contains mutation ids of the base traits. More...
 
std::vector< const mutation_branch * > cached_mutations
 Pointers to mutation branches in my_mutations. More...
 
pimpl< SkillLevelMap_skills
 Character skills. More...
 
pimpl< SkillLevelMapautolearn_skills_stamp
 Stamp of character skills. More...
 
pimpl< recipe_subsetlearned_recipes
 Subset of learned recipes. More...
 
std::bitset< NUM_VISION_MODESvision_mode_cache
 
float nv_range = 0
 
int sight_max = 0
 
time_point time_died = calendar::before_time_starts
 
pimpl< pathfinding_settingspath_settings
 Cache for pathfinding settings. More...
 
int faction_api_version = 2
 
faction_id fac_id
 
factionmy_fac = nullptr
 
character_movemode move_mode = CMM_WALK
 
std::map< vitamin_id, int > vitamin_levels
 Current deficiency/excess quantity for each vitamin. More...
 
pimpl< player_moralemorale
 
pimpl< enchantmentenchantment_cache
 
std::unordered_map< point_abs_omt, time_durationovermap_time
 Amount of time the player has spent in each overmap tile. More...
 
- Protected Attributes inherited from Creature
Creaturekiller = nullptr
 
pimpl< effects_mapeffects
 
std::unordered_map< std::string, std::string > values
 
int num_blocks = 0
 
int num_dodges = 0
 
int num_blocks_bonus = 0
 
int num_dodges_bonus = 0
 
int armor_bash_bonus = 0
 
int armor_cut_bonus = 0
 
int armor_bullet_bonus = 0
 
int speed_base = 0
 
int speed_bonus = 0
 
float speed_mult = 0.f
 
float dodge_bonus = 0.0
 
int block_bonus = 0
 
float hit_bonus = 0.0
 
bool fake = false
 

Private Member Functions

bool valid_aoe_technique (Creature &t, const ma_technique &technique)
 Check if an area-of-effect technique has valid targets. More...
 
bool valid_aoe_technique (Creature &t, const ma_technique &technique, std::vector< Creature * > &targets)
 
int get_mod (const trait_id &mut, const std::string &arg) const
 Retrieves a stat mod of a mutation. More...
 
void apply_skill_boost ()
 Applies skill-based boosts to stats. More...
 
void old_mutate ()
 
void suffer_water_damage (const mutation_branch &mdata)
 suffer() subcalls More...
 
void suffer_mutation_power (const mutation_branch &mdata, char_trait_data &tdata)
 
void suffer_while_underwater ()
 
void suffer_from_addictions ()
 
void suffer_while_awake (int current_stim)
 
void suffer_from_chemimbalance ()
 
void suffer_from_schizophrenia ()
 
void suffer_from_asthma (int current_stim)
 
void suffer_feral_kill_withdrawl ()
 
void suffer_in_sunlight ()
 
void suffer_from_sunburn ()
 
void suffer_from_other_mutations ()
 
void suffer_from_radiation ()
 
void suffer_from_bad_bionics ()
 
void suffer_from_artifacts ()
 
void suffer_from_stimulants (int current_stim)
 
void suffer_without_sleep (int sleep_deprivation)
 
bool is_visible_in_range (const Creature &critter, int range) const
 Check whether the other creature is in range and can be seen by this creature. More...
 

Private Attributes

player_activity destination_activity
 
character_id id
 
units::energy power_level
 
units::energy max_power_level
 
int stored_calories = 0
 Needs (hunger, starvation, thirst, fatigue, etc.) More...
 
int thirst = 0
 
int stamina = 0
 
int fatigue = 0
 
int sleep_deprivation = 0
 
bool check_encumbrance = true
 
int stim = 0
 
int pkill = 0
 
int radiation = 0
 
std::vector< tripointauto_move_route
 
std::optional< tripointnext_expected_position
 
scenttype_id type_of_scent
 
struct weighted_int_list< std::string > melee_miss_reasons
 
int cached_moves = 0
 
tripoint cached_position
 
inventory cached_crafting_inventory
 
std::array< double, npc_ai_info::num_npc_ai_infonpc_ai_info_cache
 
safe_reference_anchor anchor
 

Additional Inherited Members

Detailed Description

Definition at line 225 of file character.h.

Member Typedef Documentation

◆ trap_map

using Character::trap_map = std::map<tripoint, std::string>

Definition at line 2084 of file character.h.

Member Enumeration Documentation

◆ water_tolerance

Enumerator
WT_IGNORED 
WT_NEUTRAL 
WT_GOOD 
NUM_WATER_TOLERANCE 

Definition at line 791 of file character.h.

791 {
792 WT_IGNORED = 0,
794 WT_GOOD,
796 };
@ WT_NEUTRAL
Definition: character.h:793
@ WT_IGNORED
Definition: character.h:792
@ NUM_WATER_TOLERANCE
Definition: character.h:795

Constructor & Destructor Documentation

◆ Character() [1/3]

Character::Character ( const Character )
delete

◆ ~Character()

Character::~Character ( )
overridedefault

◆ Character() [2/3]

Character::Character ( )
protected

Definition at line 409 of file character.cpp.

409 :
411 damage_bandaged( {{ 0 }} ),
412 damage_disinfected( {{ 0 }} ),
414 id( -1 ),
417{
418 str_max = 0;
419 dex_max = 0;
420 per_max = 0;
421 int_max = 0;
422 str_cur = 0;
423 dex_cur = 0;
424 per_cur = 0;
425 int_cur = 0;
426 str_bonus = 0;
427 dex_bonus = 0;
428 per_bonus = 0;
429 int_bonus = 0;
430 healthy = 0;
431 healthy_mod = 0;
432 thirst = 0;
433 fatigue = 0;
435 set_rad( 0 );
436 tank_plut = 0;
437 reactor_plut = 0;
438 slow_rad = 0;
439 set_stim( 0 );
440 set_stamina( 10000 ); //Temporary value for stamina. It will be reset later from external json option.
441 set_anatomy( anatomy_id("human_anatomy") );
442 set_body();
443 update_type_of_scent( true );
444 pkill = 0;
447 healed_total = { { 0, 0, 0, 0, 0, 0 } };
448
449 name.clear();
450 custom_profession.clear();
452
453 *path_settings = pathfinding_settings{ 0, 1000, 1000, 0, true, true, true, false, true };
454
456 next_expected_position = std::nullopt;
457 temp_cur.fill( BODYTEMP_NORM );
458 frostbite_timer.fill( 0 );
459 temp_conv.fill( BODYTEMP_NORM );
460
461 body_wetness.fill( 0 );
462
475 npc_ai_info_cache.fill(-1.0);
476}
string_id< anatomy > anatomy_id
Definition: anatomy.h:14
@ bp_foot_l
Definition: bodypart.h:51
@ bp_leg_r
Definition: bodypart.h:50
@ bp_eyes
Definition: bodypart.h:43
@ bp_hand_l
Definition: bodypart.h:47
@ bp_arm_l
Definition: bodypart.h:45
@ bp_leg_l
Definition: bodypart.h:49
@ bp_hand_r
Definition: bodypart.h:48
@ bp_head
Definition: bodypart.h:42
@ bp_torso
Definition: bodypart.h:41
@ bp_mouth
Definition: bodypart.h:44
@ bp_foot_r
Definition: bodypart.h:52
@ bp_arm_r
Definition: bodypart.h:46
@ CMM_WALK
Definition: character.h:109
bool last_climate_control_ret
Definition: character.h:2298
character_movemode move_mode
Definition: character.h:2206
int str_max
Definition: character.h:259
std::array< int, num_bp > frostbite_timer
Definition: character.h:2293
void update_type_of_scent(bool init=false)
Definition: character.cpp:8728
int str_cur
Definition: character.h:264
int str_bonus
Bonuses to stats, calculated each turn.
Definition: character.h:2132
profession_id prof
Definition: character.h:573
int dex_cur
Definition: character.h:265
std::array< int, num_bp > temp_conv
Definition: character.h:2293
int max_stored_kcal() const
Definition: character.cpp:4341
int per_max
Definition: character.h:262
void set_stim(int new_stim)
Definition: character.cpp:7058
void set_stamina(int new_stamina)
Definition: character.cpp:7102
std::string name
Definition: character.h:1566
std::array< int, num_bp > body_wetness
Definition: character.h:2294
time_point next_climate_control_check
Definition: character.h:2297
int stored_calories
Needs (hunger, starvation, thirst, fatigue, etc.)
Definition: character.h:2254
int per_bonus
Definition: character.h:2134
time_point cached_time
Definition: character.h:1605
std::string custom_profession
Definition: character.h:574
int dex_bonus
Definition: character.h:2133
std::optional< tripoint > next_expected_position
Definition: character.h:2270
pimpl< pathfinding_settings > path_settings
Cache for pathfinding settings.
Definition: character.h:2195
std::array< int, num_hp_parts > damage_bandaged
Definition: character.h:1570
character_id id
Definition: character.h:2248
int healthy
How healthy the character is.
Definition: character.h:2138
int sleep_deprivation
Definition: character.h:2260
int int_cur
Definition: character.h:266
int int_max
Definition: character.h:261
int reactor_plut
Definition: character.h:1595
int fatigue
Definition: character.h:2259
std::array< int, num_bp > drench_capacity
Definition: character.h:2295
std::array< int, num_bp > temp_cur
Definition: character.h:2293
void initialize_stomach_contents()
Definition: stomach.cpp:195
std::array< int, num_hp_parts > healed_total
Definition: character.h:1779
void set_rad(int new_rad)
Definition: character.cpp:7073
int slow_rad
Definition: character.h:1596
std::array< double, npc_ai_info::num_npc_ai_info > npc_ai_info_cache
Definition: character.h:2279
int per_cur
Definition: character.h:267
int tank_plut
Definition: character.h:1594
int healthy_mod
Definition: character.h:2139
int dex_max
Definition: character.h:260
int thirst
Definition: character.h:2256
int int_bonus
Definition: character.h:2135
std::array< int, num_hp_parts > damage_disinfected
Definition: character.h:1570
void set_body()
Definition: creature.cpp:1573
void set_anatomy(anatomy_id anat)
Definition: creature.cpp:1563
static const profession_id & generic()
Definition: profession.cpp:248
const time_point before_time_starts
A time point that is always before the current turn, even when the game has just started.
Definition: calendar.cpp:25
static constexpr int BODYTEMP_NORM
Level 1 hotness.
Definition: weather.h:36

◆ Character() [3/3]

Character::Character ( Character &&  )
protecteddefault

Member Function Documentation

◆ absorb_hit()

void Character::absorb_hit ( const bodypart_id bp,
damage_instance dam 
)
overridevirtual

Runs through all bionics and armor on a part and reduces damage through their armor_absorb.

Implements Creature.

Definition at line 8023 of file character.cpp.

8024{
8025 std::list<item> worn_remains;
8026 bool armor_destroyed = false;
8027
8028 for( damage_unit &elem : dam.damage_units ) {
8029 if( elem.amount < 0 ) {
8030 // Prevents 0 damage hits (like from hallucinations) from ripping armor
8031 elem.amount = 0;
8032 continue;
8033 }
8034
8035 // The bio_ads CBM absorbs percentage melee damage and ranged damage (where possible) after armour.
8036 if( has_active_bionic( bio_ads ) && ( elem.amount > 0 ) && ( elem.type == DT_BASH ||
8037 elem.type == DT_CUT || elem.type == DT_STAB || elem.type == DT_BULLET ) ) {
8038 float elem_multi = 1;
8040 // HACK: Halves charge rate when hit for the next 3 turns, doesn't stack. See bionics.cpp for more information.
8041 bio.charge_timer = 6;
8042 // Bullet affected significantly more than stab, stab more than cut, cut more than bash.
8043 if( elem.type == DT_BASH ) {
8044 elem_multi = 0.8;
8045 } else if( elem.type == DT_CUT ) {
8046 elem_multi = 0.7;
8047 } else if( elem.type == DT_STAB ) {
8048 elem_multi = 0.55;
8049 } else if( elem.type == DT_BULLET ) {
8050 elem_multi = 0.25;
8051 }
8052 units::energy ads_cost = elem.amount * 500_J;
8053 if( bio.energy_stored >= ads_cost ) {
8054 dam.mult_damage( elem_multi );
8055 bio.energy_stored -= ads_cost;
8056 } else if( bio.energy_stored < ads_cost && bio.energy_stored != 0_kJ ) {
8057 // If you get hit and you lack energy it either deactivates, or deactivates and shorts out.
8058 // Either way you still get protection.
8059 dam.mult_damage( elem_multi );
8060 bio.energy_stored = 0_kJ;
8061 deactivate_bionic( bio );
8062 const units::energy shatter_thresh = ( elem.type == DT_BULLET ) ? 20_kJ : 15_kJ;
8063 if( ads_cost >= shatter_thresh ) {
8064 if( bio.incapacitated_time == 0_turns ) {
8065 add_msg_if_player( m_bad, _( "Your forcefield shatters and the feedback shorts out the %s!" ),
8066 bio.info().name );
8067 }
8068 int over = units::to_kilojoule( ads_cost - ( shatter_thresh - 5_kJ ) );
8069 bio.incapacitated_time += ( ( over / 5 ) ) * 1_turns;
8070 } else {
8071 add_msg_if_player( m_bad, _( "Your forcefield crackles and the %s powers down." ),
8072 bio.info().name );
8073 }
8074 } else {
8075 //You tried to (re)activate it and immediately enter combat, no mitigation for you.
8076 deactivate_bionic( bio );
8077 add_msg_if_player( m_bad, _( "The %s is interrupted and powers down." ), bio.info().name );
8078 }
8079 }
8080
8081 armor_enchantment_adjust( *this, elem );
8082
8083 // Only the outermost armor can be set on fire
8084 bool outermost = true;
8085 // The worn vector has the innermost item first, so
8086 // iterate reverse to damage the outermost (last in worn vector) first.
8087 for( auto iter = worn.rbegin(); iter != worn.rend(); ) {
8088 item &armor = *iter;
8089
8090 if( !armor.covers( bp->token ) ) {
8091 ++iter;
8092 continue;
8093 }
8094
8095 const std::string pre_damage_name = armor.tname();
8096 bool destroy = false;
8097
8098 item_armor_enchantment_adjust( *this, elem, armor );
8099 // Heat damage can set armor on fire
8100 // Even though it doesn't cause direct physical damage to it
8101 if( outermost && elem.type == DT_HEAT && elem.amount >= 1.0f ) {
8102 // TODO: Different fire intensity values based on damage
8103 fire_data frd{ 2 };
8104 destroy = armor.burn( frd );
8105 int fuel = roll_remainder( frd.fuel_produced );
8106 if( fuel > 0 ) {
8107 add_effect( effect_onfire, time_duration::from_turns( fuel + 1 ), bp->token, 0, false, true );
8108 }
8109 }
8110
8111 if( !destroy ) {
8112 destroy = armor_absorb( elem, armor );
8113 }
8114
8115 if( destroy ) {
8116 if( g->u.sees( *this ) ) {
8117 SCT.add( point( posx(), posy() ), direction::NORTH, remove_color_tags( pre_damage_name ),
8118 m_neutral, _( "destroyed" ), m_info );
8119 }
8120 destroyed_armor_msg( *this, pre_damage_name );
8121 armor_destroyed = true;
8122 armor.on_takeoff( *this );
8123 for( const item *it : armor.contents.all_items_top() ) {
8124 worn_remains.push_back( *it );
8125 }
8126 // decltype is the type name of the iterator, note that reverse_iterator::base returns the
8127 // iterator to the next element, not the one the revers_iterator points to.
8128 // http://stackoverflow.com/questions/1830158/how-to-call-erase-with-a-reverse-iterator
8129 iter = decltype( iter )( worn.erase( --( iter.base() ) ) );
8130 } else {
8131 ++iter;
8132 outermost = false;
8133 }
8134 }
8135
8136 passive_absorb_hit( bp, elem );
8137
8138 if( elem.type == DT_BASH ) {
8139 if( has_trait( trait_LIGHT_BONES ) ) {
8140 elem.amount *= 1.4;
8141 }
8142 if( has_trait( trait_HOLLOW_BONES ) ) {
8143 elem.amount *= 1.8;
8144 }
8145 }
8146
8147 elem.amount = std::max( elem.amount, 0.0f );
8148 }
8149 map &here = get_map();
8150 for( item &remain : worn_remains ) {
8151 here.add_item_or_charges( pos(), remain );
8152 }
8153 if( armor_destroyed ) {
8155 }
8156}
static const trait_id trait_HOLLOW_BONES("HOLLOW_BONES")
static void destroyed_armor_msg(Character &who, const std::string &pre_damage_name)
Definition: character.cpp:7933
static const bionic_id bio_ads("bio_ads")
static void item_armor_enchantment_adjust(const Character &guy, damage_unit &du, const item &armor)
Definition: character.cpp:7947
static const trait_id trait_LIGHT_BONES("LIGHT_BONES")
static void armor_enchantment_adjust(const Character &guy, damage_unit &du)
Definition: character.cpp:7987
static const efftype_id effect_onfire("onfire")
bionic & get_bionic_state(const bionic_id &id)
Get state of bionic with given id.
Definition: character.cpp:1803
int posx() const override
Definition: character.h:797
int posy() const override
Definition: character.h:800
std::list< item > worn
Definition: character.h:1569
bool armor_absorb(damage_unit &du, item &armor)
Reduces and mutates du, prints messages about armor taking damage.
Definition: character.cpp:8158
void drop_invalid_inventory()
Definition: character.cpp:3190
void passive_absorb_hit(const bodypart_id &bp, damage_unit &du) const
Check for relevant passive, non-clothing that can absorb damage, and reduce by specified damage unit.
Definition: character.cpp:7914
const tripoint & pos() const override
Definition: character.cpp:601
bool deactivate_bionic(bionic &bio, bool eff_only=false)
Handles bionic deactivation effects of the entered bionic, returns if anything deactivated.
Definition: bionics.cpp:1108
bool has_trait(const trait_id &b) const override
Returns true if the player has the entered trait.
Definition: mutation.cpp:101
bool has_active_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id and it is powered on.
Definition: character.cpp:1824
void add_effect(const effect &eff, bool force=false, bool deferred=false)
Definition: creature.cpp:1007
virtual void add_msg_if_player(const std::string &) const
Definition: creature.h:605
std::list< item * > all_items_top()
returns a list of pointers to all top-level items
Definition: item.h:210
item_contents contents
Definition: item.h:2161
std::string tname(unsigned int quantity=1, bool with_prefix=true, unsigned int truncate=0) const
Return the (translated) item name.
Definition: item.cpp:4574
void on_takeoff(Character &p)
Callback when a character takes off an item.
Definition: item.cpp:4415
bool burn(fire_data &frd)
Burns the item.
Definition: item.cpp:8300
bool covers(body_part bp) const
Whether this item (when worn) covers the given body part.
Definition: item.cpp:746
Manage and cache data about a part of the map.
Definition: map.h:384
item & add_item_or_charges(const tripoint &pos, item obj, bool overflow=true)
Adds an item to map tile or stacks charges.
Definition: map.cpp:4354
void add(point pos, direction p_oDir, const std::string &p_sText, game_message_type p_gmt, const std::string &p_sText2="", game_message_type p_gmt2=m_neutral, const std::string &p_sType="")
Definition: output.cpp:1757
static constexpr time_duration from_turns(const T t)
Named constructors to get a duration representing a multiple of the named time units.
Definition: calendar.h:204
@ DT_STAB
Definition: damage.h:27
@ DT_BASH
Definition: damage.h:24
@ DT_CUT
Definition: damage.h:25
@ DT_BULLET
Definition: damage.h:31
@ DT_HEAT
Definition: damage.h:28
@ m_neutral
Definition: enums.h:267
@ m_info
Definition: enums.h:265
@ m_bad
Definition: enums.h:261
std::unique_ptr< game > g
Definition: game.cpp:283
map & get_map()
Definition: map.cpp:147
constexpr value_type to_kilojoule(const quantity< value_type, energy_in_joule_tag > &v)
Definition: units_energy.h:46
std::string remove_color_tags(const std::string &s)
Removes the color tags from the input string.
Definition: output.cpp:145
scrollingcombattext SCT
Definition: output.cpp:65
int roll_remainder(double value)
Definition: rng.cpp:96
translation name
Definition: bionics.h:34
const bionic_data & info() const
Definition: bionics.h:174
int charge_timer
Definition: bionics.h:157
units::energy energy_stored
Definition: bionics.h:167
time_duration incapacitated_time
Definition: bionics.h:165
std::vector< damage_unit > damage_units
Definition: damage.h:52
void mult_damage(double multiplier, bool pre_armor=false)
Definition: damage.cpp:48
float amount
Definition: damage.h:37
damage_type type
Definition: damage.h:36
Contains the state of a fire in one tile on one turn.
Definition: fire.h:18
Definition: point.h:35
#define _(msg)
Definition: translations.h:116

References _, scrollingcombattext::add(), Creature::add_effect(), map::add_item_or_charges(), Creature::add_msg_if_player(), item_contents::all_items_top(), damage_unit::amount, armor_absorb(), armor_enchantment_adjust(), bio_ads, item::burn(), bionic::charge_timer, item::contents, item::covers(), damage_instance::damage_units, deactivate_bionic(), destroyed_armor_msg(), drop_invalid_inventory(), DT_BASH, DT_BULLET, DT_CUT, DT_HEAT, DT_STAB, effect_onfire, bionic::energy_stored, time_duration::from_turns(), g, get_bionic_state(), get_map(), has_active_bionic(), has_trait(), bionic::incapacitated_time, bionic::info(), item_armor_enchantment_adjust(), m_bad, m_info, m_neutral, damage_instance::mult_damage(), bionic_data::name, NORTH, item::on_takeoff(), passive_absorb_hit(), pos(), posx(), posy(), remove_color_tags(), roll_remainder(), SCT, item::tname(), units::to_kilojoule(), trait_HOLLOW_BONES, trait_LIGHT_BONES, damage_unit::type, and worn.

◆ action_taken()

void Character::action_taken ( )

Called after every action, invalidates player caches.

Definition at line 812 of file character.cpp.

813{
814 nv_cached = false;
815}
bool nv_cached
Definition: character.h:1571

References nv_cached.

Referenced by game::do_turn().

◆ activate_bionic()

bool Character::activate_bionic ( bionic bio,
bool  eff_only = false 
)

Handles bionic activation effects of the entered bionic, returns if anything activated.

Definition at line 589 of file bionics.cpp.

590{
591 const bool mounted = is_mounted();
592 if( bio.incapacitated_time > 0_turns ) {
593 add_msg_if_player( m_info, _( "Your %s is shorting out and can't be activated." ),
594 bio.info().name );
595 return false;
596 }
597
598 // eff_only means only do the effect without messing with stats or displaying messages
599 if( !eff_only ) {
600 if( bio.powered ) {
601 // It's already on!
602 return false;
603 }
604 if( !enough_power_for( bio.id ) ) {
605 add_msg_if_player( m_info, _( "You don't have the power to activate your %s." ),
606 bio.info().name );
607 return false;
608 }
609
610 // HACK: burn_fuel() doesn't check for available fuel in remote source on start.
611 // If CBM is successfully activated, the check will occur when it actually tries to draw power
612 if( !bio.info().is_remote_fueled ) {
613 if( !burn_fuel( bio, true ) ) {
614 return false;
615 }
616 }
617
618 // We can actually activate now, do activation-y things
620
621 bio.powered = bio.info().has_flag( flag_BIONIC_TOGGLED ) || bio.info().charge_time > 0;
622
623 if( bio.info().charge_time > 0 ) {
624 bio.charge_timer = bio.info().charge_time;
625 }
626 if( !bio.id->enchantments.empty() ) {
628 }
629 }
630
631 auto add_msg_activate = [&]() {
632 if( !eff_only && !bio.is_auto_start_keep_full() ) {
633 add_msg_if_player( m_info, _( "You activate your %s." ), bio.info().name );
634 } else if( get_player_character().sees( pos() ) ) {
635 add_msg( m_info, _( "%s activates their %s." ), disp_name(),
636 bio.info().name );
637 }
638 };
639 auto refund_power = [&]() {
640 if( !eff_only ) {
642 }
643 };
644
645 item tmp_item;
646 const w_point &weatherPoint = get_weather().get_precise();
647
648 map &here = get_map();
649 // On activation effects go here
650 if( bio.info().has_flag( flag_BIONIC_GUN ) ) {
651 add_msg_activate();
652 refund_power(); // Power usage calculated later, in avatar_action::fire
654 bio.info().power_activate );
655 } else if( bio.info().has_flag( flag_BIONIC_WEAPON ) ) {
657 add_msg_if_player( m_info, _( "Deactivate your %s first!" ), primary_weapon().tname() );
658 refund_power();
659 bio.powered = false;
660 return false;
661 }
662
663 if( !primary_weapon().is_null() ) {
664 const std::string query = string_format( _( "Stop wielding %s?" ), primary_weapon().tname() );
665 if( !dispose_item( item_location( *this, &primary_weapon() ), query ) ) {
666 refund_power();
667 bio.powered = false;
668 return false;
669 }
670 }
671
672 add_msg_activate();
674 primary_weapon().invlet = '#';
675 if( is_player() && bio.ammo_count > 0 ) {
678 }
680 } else if( bio.id == bio_ears && has_active_bionic( bio_earplugs ) ) {
681 add_msg_activate();
682 for( bionic &bio : *my_bionics ) {
683 if( bio.id == bio_earplugs ) {
684 bio.powered = false;
685 add_msg_if_player( m_info, _( "Your %s automatically turn off." ),
686 bio.info().name );
687 }
688 }
689 } else if( bio.id == bio_earplugs && has_active_bionic( bio_ears ) ) {
690 add_msg_activate();
691 for( bionic &bio : *my_bionics ) {
692 if( bio.id == bio_ears ) {
693 bio.powered = false;
694 add_msg_if_player( m_info, _( "Your %s automatically turns off." ),
695 bio.info().name );
696 }
697 }
698 } else if( bio.id == bio_evap ) {
699 add_msg_activate();
700 const w_point &weatherPoint = get_weather().get_precise();
701 int humidity = get_local_humidity( weatherPoint.humidity, get_weather().weather_id,
702 g->is_sheltered( g->u.pos() ) );
703 // thirst units = 5 mL
704 int water_available = std::lround( humidity * 3.0 / 100.0 );
705 if( water_available == 0 ) {
706 bio.powered = false;
707 add_msg_if_player( m_bad, _( "There is not enough humidity in the air for your %s to function." ),
708 bio.info().name );
709 return false;
710 } else if( water_available == 1 ) {
712 _( "Your %s issues a low humidity warning. Efficiency will be reduced." ),
713 bio.info().name );
714 }
715 } else if( bio.id == bio_tools ) {
716 add_msg_activate();
718 } else if( bio.id == bio_cqb ) {
719 add_msg_activate();
720 const avatar *you = as_avatar();
721 if( you && !martial_arts_data->pick_style( *you ) ) {
722 bio.powered = false;
723 add_msg_if_player( m_info, _( "You change your mind and turn it off." ) );
724 return false;
725 }
726 } else if( bio.id == bio_resonator ) {
727 add_msg_activate();
728 //~Sound of a bionic sonic-resonator shaking the area
729 sounds::sound( pos(), 30, sounds::sound_t::combat, _( "VRRRRMP!" ), false, "bionic",
730 static_cast<std::string>( bio_resonator ) );
731 for( const tripoint &bashpoint : here.points_in_radius( pos(), 1 ) ) {
732 here.bash( bashpoint, 110 );
733 // Multibash effect, so that doors &c will fall
734 here.bash( bashpoint, 110 );
735 here.bash( bashpoint, 110 );
736 }
737
738 mod_moves( -100 );
739 } else if( bio.id == bio_time_freeze ) {
740 if( mounted ) {
741 refund_power();
742 add_msg_if_player( m_info, _( "You cannot activate %s while mounted." ), bio.info().name );
743 return false;
744 }
745 add_msg_activate();
746
748 set_power_level( 0_kJ );
749 add_msg_if_player( m_good, _( "Your speed suddenly increases!" ) );
750 if( one_in( 3 ) ) {
751 add_msg_if_player( m_bad, _( "Your muscles tear with the strain." ) );
752 apply_damage( nullptr, bodypart_id( "arm_l" ), rng( 5, 10 ) );
753 apply_damage( nullptr, bodypart_id( "arm_r" ), rng( 5, 10 ) );
754 apply_damage( nullptr, bodypart_id( "leg_l" ), rng( 7, 12 ) );
755 apply_damage( nullptr, bodypart_id( "leg_r" ), rng( 7, 12 ) );
756 apply_damage( nullptr, bodypart_id( "torso" ), rng( 5, 15 ) );
757 }
758 if( one_in( 5 ) ) {
759 add_effect( effect_teleglow, rng( 5_minutes, 40_minutes ) );
760 }
761 } else if( bio.id == bio_teleport ) {
762 if( mounted ) {
763 refund_power();
764 add_msg_if_player( m_info, _( "You cannot activate %s while mounted." ), bio.info().name );
765 return false;
766 }
767 add_msg_activate();
768
769 teleport::teleport( *this );
770 add_effect( effect_teleglow, 30_minutes );
771 mod_moves( -100 );
772 } else if( bio.id == bio_blood_anal ) {
773 add_msg_activate();
775 } else if( bio.id == bio_blood_filter ) {
776 add_msg_activate();
777 static const std::vector<efftype_id> removable = {{
785 }
786 };
787
788 for( const auto &eff : removable ) {
789 remove_effect( eff );
790 }
791 // Purging the substance won't remove the fatigue it caused
794 set_painkiller( 0 );
795 set_stim( 0 );
796 mod_moves( -100 );
797 } else if( bio.id == bio_torsionratchet ) {
798 add_msg_activate();
799 add_msg_if_player( m_info, _( "Your torsion ratchet locks onto your joints." ) );
800 } else if( bio.id == bio_jointservo ) {
801 add_msg_activate();
802 add_msg_if_player( m_info, _( "You can now run faster, assisted by joint servomotors." ) );
803 } else if( bio.id == bio_lighter ) {
804 const std::optional<tripoint> pnt = choose_adjacent( _( "Start a fire where?" ) );
805 if( pnt && here.is_flammable( *pnt ) ) {
806 add_msg_activate();
807 here.add_field( *pnt, fd_fire, 1 );
808 mod_moves( -100 );
809 } else {
810 refund_power();
811 add_msg_if_player( m_info, _( "There's nothing to light there." ) );
812 return false;
813 }
814 } else if( bio.id == bio_geiger ) {
815 add_msg_activate();
816 add_msg_if_player( m_info, _( "Your radiation level: %d" ), get_rad() );
817 } else if( bio.id == bio_adrenaline ) {
818 add_msg_activate();
820 add_msg_if_player( m_bad, _( "Safeguards kick in, and the bionic refuses to activate!" ) );
821 refund_power();
822 return false;
823 } else {
824 add_msg_activate();
825 add_effect( effect_adrenaline, 20_minutes );
826 }
827 } else if( bio.id == bio_emp ) {
828 if( const std::optional<tripoint> pnt = choose_adjacent( _( "Create an EMP where?" ) ) ) {
829 add_msg_activate();
831 mod_moves( -100 );
832 } else {
833 refund_power();
834 return false;
835 }
836 } else if( bio.id == bio_hydraulics ) {
837 add_msg_activate();
838 add_msg_if_player( m_good, _( "Your muscles hiss as hydraulic strength fills them!" ) );
839 //~ Sound of hissing hydraulic muscle! (not quite as loud as a car horn)
840 sounds::sound( pos(), 19, sounds::sound_t::activity, _( "HISISSS!" ), false, "bionic",
841 static_cast<std::string>( bio_hydraulics ) );
842 } else if( bio.id == bio_water_extractor ) {
843 bool no_target = true;
844 bool extracted = false;
845 for( item &it : here.i_at( pos() ) ) {
846 static const auto volume_per_water_charge = 500_ml;
847 if( it.is_corpse() ) {
848 const int avail = it.get_var( "remaining_water", it.volume() / volume_per_water_charge );
849 if( avail > 0 ) {
850 no_target = false;
851 if( query_yn( _( "Extract water from the %s" ),
852 colorize( it.tname(), it.color_in_inventory() ) ) ) {
853 item water( itype_water_clean, calendar::turn, avail );
854 if( liquid_handler::consume_liquid( water ) ) {
855 add_msg_activate();
856 extracted = true;
857 it.set_var( "remaining_water", static_cast<int>( water.charges ) );
858 }
859 break;
860 }
861 }
862 }
863 }
864 if( no_target ) {
865 add_msg_if_player( m_bad, _( "There is no suitable corpse on this tile." ) );
866 }
867 if( !extracted ) {
868 refund_power();
869 return false;
870 }
871 } else if( bio.id == bio_magnet ) {
872 add_msg_activate();
873 static const std::set<material_id> affected_materials =
874 { material_id( "iron" ), material_id( "steel" ) };
875 // Remember all items that will be affected, then affect them
876 // Don't "snowball" by affecting some items multiple times
877 std::vector<std::pair<item, tripoint>> affected;
878 const units::mass weight_cap = weight_capacity();
879 for( const tripoint &p : here.points_in_radius( pos(), 10 ) ) {
880 if( p == pos() || !here.has_items( p ) || here.has_flag( flag_SEALED, p ) ) {
881 continue;
882 }
883
884 map_stack stack = here.i_at( p );
885 for( auto it = stack.begin(); it != stack.end(); it++ ) {
886 if( it->weight() < weight_cap &&
887 it->made_of_any( affected_materials ) ) {
888 affected.emplace_back( std::make_pair( *it, p ) );
889 stack.erase( it );
890 break;
891 }
892 }
893 }
894
895 for( const std::pair<item, tripoint> &pr : affected ) {
896 projectile proj;
897 proj.speed = 50;
898 proj.impact = damage_instance::physical( pr.first.weight() / 250_gram, 0, 0, 0 );
899 // make the projectile stop one tile short to prevent hitting the player
900 proj.range = rl_dist( pr.second, pos() ) - 1;
901 static const std::set<ammo_effect_str_id> ammo_effects = {{
902 ammo_effect_str_id( "NO_ITEM_DAMAGE" ),
903 ammo_effect_str_id( "DRAW_AS_LINE" ),
904 ammo_effect_str_id( "NO_DAMAGE_SCALING" ),
905 ammo_effect_str_id( "JET" ),
906 }
907 };
908 for( const auto &eff : ammo_effects ) {
909 proj.add_effect( eff );
910 }
911
913 proj, pr.second, pos(), dispersion_sources{ 0 }, this );
914 here.add_item_or_charges( dealt.end_point, pr.first );
915 }
916
917 mod_moves( -100 );
918 } else if( bio.id == bio_lockpick ) {
919 bool used = false;
920 bool tried_lockpick = false;
921 const std::optional<tripoint> pnt = choose_adjacent( _( "Use your lockpick where?" ) );
922 std::string open_message;
923 if( pnt ) {
924 tried_lockpick = true;
925 ter_id ter_type = g->m.ter( *pnt );
926 furn_id furn_type = g->m.furn( *pnt );
927 lockpicking_open_result lr = get_lockpicking_open_result( ter_type, furn_type );
928 ter_id new_ter_type = lr.new_ter_type;
929 furn_id new_furn_type = lr.new_furn_type;
930 open_message = lr.open_message;
931
932 if( new_ter_type != t_null || new_furn_type != f_null ) {
933 g->m.has_furn( *pnt ) ?
934 g->m.furn_set( *pnt, new_furn_type ) :
935 static_cast<void>( g->m.ter_set( *pnt, new_ter_type ) );
936 used = true;
937 }
938 }
939
940 if( used ) {
941 add_msg_activate();
942 add_msg_if_player( m_good, open_message );
943 mod_moves( -100 );
944 } else {
945 refund_power();
946 if( tried_lockpick ) {
947 add_msg_if_player( m_info, _( "There is nothing to lockpick nearby." ) );
948 }
949 return false;
950 }
951 } else if( bio.id == bio_flashbang ) {
952 add_msg_activate();
953 explosion_handler::flashbang( pos(), true, "explosion" );
954 mod_moves( -100 );
955 } else if( bio.id == bio_shockwave ) {
956 add_msg_activate();
957
959 sw.affects_player = false;
960 sw.radius = 3;
961 sw.force = 4;
962 sw.stun = 2;
963 sw.dam_mult = 8;
964 // affects_player is always false, so assuming the player is always the source of this
965 explosion_handler::shockwave( pos(), sw, "explosion", &get_player_character() );
966 add_msg_if_player( m_neutral, _( "You unleash a powerful shockwave!" ) );
967 mod_moves( -100 );
968 } else if( bio.id == bio_meteorologist ) {
970 add_msg_activate();
971 // Calculate local wind power
972 int vehwindspeed = 0;
973 if( optional_vpart_position vp = here.veh_at( pos() ) ) {
974 // vehicle velocity in mph
975 vehwindspeed = std::abs( vp->vehicle().velocity / 100 );
976 }
977 const oter_id &cur_om_ter = overmap_buffer.ter( global_omt_location() );
978 /* cache g->get_temperature( player location ) since it is used twice. No reason to recalc */
979 const auto player_local_temp = weather.get_temperature( g->u.pos() );
980 /* windpower defined in internal velocity units (=.01 mph) */
981 double windpower = 100.0f * get_local_windpower( weather.windspeed + vehwindspeed,
982 cur_om_ter, pos(), weather.winddirection, g->is_sheltered( pos() ) );
983 add_msg_if_player( m_info, _( "Temperature: %s." ), print_temperature( player_local_temp ) );
984 add_msg_if_player( m_info, _( "Relative Humidity: %s." ),
986 get_local_humidity( weatherPoint.humidity, weather.weather_id,
987 g->is_sheltered( g->u.pos() ) ) ) );
988 add_msg_if_player( m_info, _( "Pressure: %s." ),
989 print_pressure( static_cast<int>( weatherPoint.pressure ) ) );
990 add_msg_if_player( m_info, _( "Wind Speed: %.1f %s." ),
991 convert_velocity( static_cast<int>( windpower ), VU_WIND ),
993 add_msg_if_player( m_info, _( "Feels Like: %s." ),
996 weatherPoint.humidity,
997 windpower / 100 ) + player_local_temp ) );
998 std::string dirstring = get_dirstring( weather.winddirection );
999 add_msg_if_player( m_info, _( "Wind Direction: From the %s." ), dirstring );
1000 } else if( bio.id == bio_remote ) {
1001 add_msg_activate();
1002 int choice = uilist( _( "Perform which function:" ), {
1003 _( "Control vehicle" ), _( "RC radio" )
1004 } );
1005 if( choice >= 0 && choice <= 1 ) {
1006 item ctr;
1007 if( choice == 0 ) {
1008 ctr = item( "remotevehcontrol", calendar::start_of_cataclysm );
1009 } else {
1010 ctr = item( "radiocontrol", calendar::start_of_cataclysm );
1011 }
1013 int power_use = invoke_item( &ctr );
1014 mod_power_level( units::from_kilojoule( -power_use ) );
1015 bio.powered = ctr.active;
1016 } else {
1017 bio.powered = g->remoteveh() != nullptr || !get_value( "remote_controlling" ).empty();
1018 }
1019 } else if( bio.info().is_remote_fueled ) {
1020 std::vector<item *> cables = items_with( []( const item & it ) {
1021 return it.has_flag( flag_CABLE_SPOOL );
1022 } );
1023 bool has_cable = !cables.empty();
1024 bool free_cable = false;
1025 bool success = false;
1026 if( !has_cable ) {
1028 _( "You need a jumper cable connected to a power source to drain power from it." ) );
1029 } else {
1030 for( item *cable : cables ) {
1031 const std::string state = cable->get_var( "state" );
1032 if( state == "cable_charger" ) {
1034 _( "Cable is plugged-in to the CBM but it has to be also connected to the power source." ) );
1035 }
1036 if( state == "cable_charger_link" ) {
1037 add_msg_activate();
1038 success = true;
1040 _( "You are plugged to the vehicle. It will charge you if it has some juice in it." ) );
1041 }
1042 if( state == "solar_pack_link" ) {
1043 add_msg_activate();
1044 success = true;
1046 _( "You are plugged to a solar pack. It will charge you if it's unfolded and in sunlight." ) );
1047 }
1048 if( state == "UPS_link" ) {
1049 add_msg_activate();
1050 success = true;
1052 _( "You are plugged to a UPS. It will charge you if it has some juice in it." ) );
1053 }
1054 if( state == "solar_pack" || state == "UPS" ) {
1056 _( "You have a cable plugged to a portable power source, but you need to plug it in to the CBM." ) );
1057 }
1058 if( state == "pay_out_cable" ) {
1060 _( "You have a cable plugged to a vehicle, but you need to plug it in to the CBM." ) );
1061 }
1062 if( state == "attach_first" ) {
1063 free_cable = true;
1064 }
1065 }
1066
1067 if( free_cable ) {
1069 _( "You have at least one free cable in your inventory that you could use to plug yourself in." ) );
1070 }
1071 }
1072 if( !success ) {
1073 refund_power();
1074 bio.powered = false;
1075 return false;
1076 }
1077
1078 } else if( bio.id == bio_probability_travel ) {
1079 if( const std::optional<tripoint> pnt = choose_adjacent( _( "Tunnel in which direction?" ) ) ) {
1080 if( g->m.impassable( *pnt ) ) {
1081 add_msg_activate();
1082 g->phasing_move( *pnt );
1083 } else {
1084 refund_power();
1085 add_msg_if_player( m_info, _( "There's nothing to phase through there." ) );
1086 return false;
1087 }
1088 } else {
1089 refund_power();
1090 return false;
1091 }
1092 } else {
1093 add_msg_activate();
1094 }
1095
1096 // Recalculate stats (strength, mods from pain etc.) that could have been affected
1098 reset();
1099
1100 // Also reset crafting inventory cache if this bionic spawned a fake item
1101 if( !bio.info().fake_item.is_empty() ) {
1103 }
1104
1105 return true;
1106}
std::optional< tripoint > choose_adjacent(const std::string &message, const bool allow_vertical)
Request player input of adjacent tile, possibly including vertical tiles.
Definition: action.cpp:980
units::quantity< V, B > rng(const units::quantity< V, B > &min, const units::quantity< V, B > &max)
Definition: artifact.cpp:32
dealt_projectile_attack projectile_attack(const projectile &proj_arg, const tripoint &source, const tripoint &target_arg, const dispersion_sources &dispersion, Creature *origin, const vehicle *in_veh)
Fires a projectile at the target point from the source point with total_dispersion dispersion.
Definition: ballistics.cpp:201
static const flag_str_id flag_BIONIC_WEAPON("BIONIC_WEAPON")
static const bionic_id bio_cqb("bio_cqb")
static const bionic_id bio_geiger("bio_geiger")
static const itype_id itype_water_clean("water_clean")
static const efftype_id effect_bloodworms("bloodworms")
static const flag_str_id flag_BIONIC_GUN("BIONIC_GUN")
static const efftype_id effect_weed_high("weed_high")
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_pkill_l("pkill_l")
static const efftype_id effect_took_prozac("took_prozac")
static const efftype_id effect_datura("datura")
static const efftype_id effect_drunk("drunk")
static const efftype_id effect_teleglow("teleglow")
static const efftype_id effect_badpoison("badpoison")
static const efftype_id effect_dermatik("dermatik")
static const std::string flag_NO_UNWIELD("NO_UNWIELD")
static const efftype_id effect_pkill2("pkill2")
static const efftype_id effect_adrenaline("adrenaline")
static void force_comedown(effect &eff)
Definition: bionics.cpp:448
static const bionic_id bio_evap("bio_evap")
static const efftype_id effect_took_flumed("took_flumed")
static const efftype_id effect_hallu("hallu")
static const efftype_id effect_pblue("pblue")
static const bionic_id bio_water_extractor("bio_water_extractor")
static const bionic_id bio_hydraulics("bio_hydraulics")
static const efftype_id effect_cocaine_high("cocaine_high")
static const bionic_id bio_lighter("bio_lighter")
static const bionic_id bio_magnet("bio_magnet")
static const efftype_id effect_meth("meth")
static const bionic_id bio_flashbang("bio_flashbang")
static const bionic_id bio_time_freeze("bio_time_freeze")
static const bionic_id bio_meteorologist("bio_meteorologist")
static const std::string flag_CABLE_SPOOL("CABLE_SPOOL")
static const efftype_id effect_visuals("visuals")
static const bionic_id bio_ears("bio_ears")
static const bionic_id bio_shockwave("bio_shockwave")
static const bionic_id bio_emp("bio_emp")
static const bionic_id bio_remote("bio_remote")
static const efftype_id effect_stung("stung")
static const std::string flag_SEALED("SEALED")
static const flag_str_id flag_BIONIC_TOGGLED("BIONIC_TOGGLED")
static const efftype_id effect_cig("cig")
static const bionic_id bio_tools("bio_tools")
static const bionic_id bio_earplugs("bio_earplugs")
static const bionic_id bio_adrenaline("bio_adrenaline")
static const bionic_id bio_lockpick("bio_lockpick")
static const bionic_id bio_blood_anal("bio_blood_anal")
static const bionic_id bio_probability_travel("bio_probability_travel")
static const bionic_id bio_teleport("bio_teleport")
static const efftype_id effect_poison("poison")
static const bionic_id bio_resonator("bio_resonator")
static const bionic_id bio_blood_filter("bio_blood_filter")
static const efftype_id effect_pkill1("pkill1")
static const efftype_id effect_took_xanax("took_xanax")
static const efftype_id effect_pkill3("pkill3")
static const efftype_id effect_took_prozac_bad("took_prozac_bad")
static const bionic_id bio_torsionratchet("bio_torsionratchet")
static const efftype_id effect_iodine("iodine")
static const bionic_id bio_jointservo("bio_jointservo")
int_id< body_part_type > bodypart_id
Definition: bodypart.h:24
Character & get_player_character()
Definition: character.cpp:402
@ ideal_weapon_value
Definition: character.h:101
units::mass weight_capacity() const override
Definition: character.cpp:2626
void conduct_blood_analysis() const
Definition: character.cpp:1961
void mod_power_level(const units::energy &npower)
Definition: character.cpp:1924
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Returns either "you" or the player's name.
Definition: character.cpp:580
pimpl< character_martial_arts > martial_arts_data
Definition: character.h:1588
bool query_yn(const char *const msg, Args &&... args) const
It is supposed to hide the query_yn to simplify player vs.
Definition: character.h:1497
pimpl< bionic_collection > my_bionics
Definition: character.h:1587
virtual bool invoke_item(item *, const tripoint &pt)
Asks how to use the item (if it has more than one use_method) and uses it.
Definition: character.cpp:7224
bool burn_fuel(bionic &bio, bool start=false)
Convert fuel to bionic power.
Definition: bionics.cpp:1196
void set_power_level(const units::energy &npower)
Definition: character.cpp:1914
void set_painkiller(int npkill)
Sets intensity of painkillers
Definition: character.cpp:9793
bool is_mounted() const
Definition: character.cpp:1082
void clear_npc_ai_info_cache(npc_ai_info key) const
void apply_damage(Creature *source, bodypart_id hurt, int dam, bool bypass_med=false) override
Actually hurt the player, hurts a body_part directly, no armor reduction.
Definition: character.cpp:8402
bool enough_power_for(const bionic_id &bid) const
Definition: character.cpp:1956
void set_primary_weapon(const item &new_weapon)
Use this when primary weapon might not exist yet.
Definition: melee.cpp:171
item & primary_weapon()
Legacy code hack, don't use.
Definition: melee.cpp:166
void recalculate_enchantment_cache()
Definition: character.cpp:7856
int get_rad() const
Definition: character.cpp:7068
bool sees(const tripoint &t, bool is_player=false, int range_mod=0) const override
virtual bool dispose_item(item_location &&obj, const std::string &prompt=std::string())
Drop, wear, stash or otherwise try to dispose of an item consuming appropriate moves.
Definition: character.cpp:7263
void reset() override
Handles stat and bonus reset.
Definition: character.cpp:3645
void reset_encumbrance()
Recalculates encumbrance cache.
Definition: character.cpp:3666
units::energy get_power_level() const
Definition: character.cpp:1904
tripoint_abs_omt global_omt_location() const
Returns the location of the player in global overmap terrain coordinates.
Definition: character.cpp:6268
void invalidate_crafting_inventory()
Definition: crafting.cpp:598
virtual bool is_player() const
Definition: creature.h:92
std::string get_value(const std::string &key) const
Definition: creature.cpp:1381
bool has_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Check if creature has the matching effect.
Definition: creature.cpp:1206
bool remove_effect(const efftype_id &eff_id, body_part bp=num_bp)
Removes a listed effect.
Definition: creature.cpp:1163
void mod_moves(int nmoves)
Definition: creature.cpp:1448
const effect & get_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Return the effect that matches the given arguments exactly.
Definition: creature.cpp:1246
virtual bool has_flag(const m_flag) const
Definition: creature.h:491
virtual avatar * as_avatar()
Definition: creature.h:128
Definition: avatar.h:55
A lightweight handle to an item independent of it's location Unlike a raw pointer can be (de-)seriali...
Definition: item_location.h:23
iterator begin()
Definition: item_stack.cpp:28
iterator end()
Definition: item_stack.cpp:33
bool active
Definition: item.h:2237
item & ammo_set(const itype_id &ammo, int qty=-1)
Filter setting the ammo for this instance Any existing ammo is removed.
Definition: item.cpp:593
int charges
Definition: item.h:2199
bool has_flag(const std::string &flag) const
Definition: item.cpp:5328
char invlet
Definition: item.h:2236
Definition: map.h:105
iterator erase(const_iterator it) override
Definition: map.cpp:153
bash_results bash(const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
Returns a pair where first is whether anything was smashed and second is if it was destroyed.
Definition: map.cpp:3623
bool has_flag(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2374
bool add_field(const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
Add field entry at point, or set intensity if present.
Definition: map.cpp:5535
tripoint_range< tripoint > points_in_radius(const tripoint &center, size_t radius, size_t radiusz=0) const
Definition: map.cpp:8761
map_stack i_at(const tripoint &p)
Definition: map.cpp:4209
bool is_flammable(const tripoint &p)
Returns true if there is a flammable item or field or the furn/terrain is flammable at p.
Definition: map.cpp:2704
optional_vpart_position veh_at(const tripoint &p) const
Checks if tile is occupied by vehicle and by which part.
Definition: map.cpp:1073
bool has_items(const tripoint &p) const
Checks for existence of items.
Definition: map.cpp:4890
Simple wrapper to forward functions that may return a std::optional to vpart_position.
const oter_id & ter(const tripoint_abs_omt &p)
Returns the overmap terrain at the given OMT coordinates.
bool is_empty() const
Returns whether this id is empty.
Definition: string_id.h:298
uilist: scrolling vertical list menu
Definition: ui.h:187
std::vector< item * > items_with(const std::function< bool(const item &)> &filter)
Returns all items (including those within a container) matching the filter.
Definition: visitable.cpp:324
const w_point & get_precise() const
Definition: weather.h:218
std::string colorize(const std::string &text, const nc_color &color)
Definition: color.cpp:669
int rl_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:519
@ m_good
Definition: enums.h:260
@ m_mixed
Definition: enums.h:262
field_type_id fd_fire
Definition: field_type.cpp:345
double get_local_windpower(double windpower, const oter_id &omter, const tripoint &location, const int &winddirection, bool sheltered)
Definition: weather.cpp:938
int get_local_humidity(double humidity, const weather_type_id &weather, bool sheltered)
Definition: weather.cpp:924
std::string print_temperature(double fahrenheit, int decimals)
Print temperature (and convert to Celsius if Celsius display is enabled.)
Definition: weather.cpp:717
std::string get_dirstring(int angle)
Definition: weather.cpp:874
weather_manager & get_weather()
Definition: weather.cpp:64
std::string print_pressure(double pressure, int decimals)
Print pressure (no conversions.)
Definition: weather.cpp:752
std::string print_humidity(double humidity, int decimals)
Print relative humidity (no conversions.)
Definition: weather.cpp:743
int get_local_windchill(double temperature_f, double humidity, double wind_mph)
Definition: weather.cpp:797
string_id< ammo_effect > ammo_effect_str_id
Definition: map.cpp:104
lockpicking_open_result get_lockpicking_open_result(ter_id ter_type, furn_id furn_type)
Gets lockpicked object and message.
Definition: mapdata.cpp:1062
ter_id t_null
Definition: mapdata.cpp:625
furn_id f_null
Definition: mapdata.cpp:1097
void add_msg(std::string msg)
Definition: messages.cpp:910
void fire_wielded_weapon(avatar &you)
Checks if the wielded weapon is a gun and can be fired then starts interactive aiming.
void fire_ranged_bionic(avatar &you, const item &fake_gun, const units::energy &cost_per_shot)
Stores fake gun specified by the bionic and starts interactive aiming.
@ success
Definition: behavior.h:20
const time_point & start_of_cataclysm
Definition: calendar.cpp:33
time_point turn
Definition: calendar.cpp:36
void shockwave(const tripoint &p, const shockwave_data &sw, const std::string &exp_name, Creature *source)
Shockwave applies knockback with given parameters to all targets within radius of p.
Definition: explosion.cpp:1612
void flashbang(const tripoint &p, bool player_immune, const std::string &exp_name)
Triggers a flashbang explosion at p.
Definition: explosion.cpp:1552
void emp_blast(const tripoint &p)
Triggers an EMP blast at p.
Definition: explosion.cpp:1671
bool consume_liquid(item &liquid, const int radius)
Consume / handle as much of the liquid as possible in varying ways.
void sound(const tripoint &p, int vol, sound_t category, const std::string &description, bool ambient=false, const std::string &id="", const std::string &variant="default")
Sound at (p) of intensity (vol)
Definition: sounds.cpp:177
bool teleport(Creature &critter, int min_distance=2, int max_distance=12, bool safe=false, bool add_teleglow=true)
Teleports a creature to a tile within min_distance and max_distance tiles.
Definition: teleport.cpp:24
constexpr value_type to_fahrenheit(const quantity< value_type, temperature_in_millidegree_celsius_tag > &v)
constexpr quantity< value_type, energy_in_joule_tag > from_kilojoule(const value_type v)
Definition: units_energy.h:32
overmapbuffer overmap_buffer
bool one_in(int chance)
Definition: rng.cpp:65
std::string string_format(std::string_view format, Args &&...args)
Simple wrapper over string_formatter::parse.
std::vector< enchantment_id > enchantments
bionic enchantments
Definition: bionics.h:113
itype_id fake_item
Fake item created for crafting with this bionic available.
Definition: bionics.h:105
units::energy power_activate
Power cost on activation.
Definition: bionics.h:37
int charge_time
How often a bionic draws or produces power while active in turns.
Definition: bionics.h:47
bool is_remote_fueled
This bionic draws power through a cable.
Definition: bionics.h:65
bool has_flag(const flag_str_id &flag) const
Definition: bionics.cpp:245
itype_id ammo_loaded
Definition: bionics.h:161
bool is_auto_start_keep_full() const
Definition: bionics.cpp:2834
bionic_id id
Definition: bionics.h:156
unsigned int ammo_count
Definition: bionics.h:163
bool powered
Definition: bionics.h:159
static damage_instance physical(float bash, float cut, float stab, float arpen=0.0f)
Definition: damage.cpp:27
std::string open_message
Definition: mapdata.h:165
void add_effect(const ammo_effect_str_id &id)
Definition: projectile.h:58
damage_instance impact
Definition: projectile.h:21
bool affects_player
Definition: explosion.h:30
units::temperature temperature
Definition: weather_gen.h:16
double humidity
Definition: weather_gen.h:17
double pressure
Definition: weather_gen.h:18
string_id< material_type > material_id
Definition: type_id.h:95
double convert_velocity(int velocity, const units_type vel_units)
Convert internal velocity units to units defined by user.
const char * velocity_units(const units_type vel_units)
Create a units label for a velocity value.
@ VU_WIND
Definition: units_utility.h:15

References _, item::active, sounds::activity, projectile::add_effect(), Creature::add_effect(), map::add_field(), map::add_item_or_charges(), add_msg(), Creature::add_msg_if_player(), shockwave_data::affects_player, bionic::ammo_count, bionic::ammo_loaded, item::ammo_set(), apply_damage(), Creature::as_avatar(), map::bash(), item_stack::begin(), bio_adrenaline, bio_blood_anal, bio_blood_filter, bio_cqb, bio_earplugs, bio_ears, bio_emp, bio_evap, bio_flashbang, bio_geiger, bio_hydraulics, bio_jointservo, bio_lighter, bio_lockpick, bio_magnet, bio_meteorologist, bio_probability_travel, bio_remote, bio_resonator, bio_shockwave, bio_teleport, bio_time_freeze, bio_tools, bio_torsionratchet, bio_water_extractor, burn_fuel(), bionic_data::charge_time, bionic::charge_timer, item::charges, choose_adjacent(), clear_npc_ai_info_cache(), colorize(), sounds::combat, conduct_blood_analysis(), liquid_handler::consume_liquid(), convert_velocity(), shockwave_data::dam_mult, disp_name(), dispose_item(), effect_adrenaline, effect_badpoison, effect_bloodworms, effect_cig, effect_cocaine_high, effect_datura, effect_dermatik, effect_drunk, effect_fungus, effect_hallu, effect_iodine, effect_meth, effect_pblue, effect_pkill1, effect_pkill2, effect_pkill3, effect_pkill_l, effect_poison, effect_stung, effect_teleglow, effect_took_flumed, effect_took_prozac, effect_took_prozac_bad, effect_took_xanax, effect_visuals, effect_weed_high, explosion_handler::emp_blast(), bionic_data::enchantments, item_stack::end(), dealt_projectile_attack::end_point, enough_power_for(), map_stack::erase(), f_null, bionic_data::fake_item, fd_fire, avatar_action::fire_ranged_bionic(), avatar_action::fire_wielded_weapon(), flag_BIONIC_GUN, flag_BIONIC_TOGGLED, flag_BIONIC_WEAPON, flag_CABLE_SPOOL(), flag_NO_UNWIELD(), flag_SEALED(), explosion_handler::flashbang(), shockwave_data::force, force_comedown(), units::from_kilojoule(), g, get_dirstring(), Creature::get_effect(), get_local_humidity(), get_local_windchill(), get_local_windpower(), get_lockpicking_open_result(), get_map(), get_player_character(), get_power_level(), weather_manager::get_precise(), get_rad(), Creature::get_value(), get_weather(), global_omt_location(), has_active_bionic(), Creature::has_effect(), bionic_data::has_flag(), Creature::has_flag(), item::has_flag(), map::has_flag(), map::has_items(), w_point::humidity, map::i_at(), bionic::id, ideal_weapon_value, projectile::impact, bionic::incapacitated_time, bionic::info(), invalidate_crafting_inventory(), item::invlet, invoke_item(), bionic::is_auto_start_keep_full(), string_id< T >::is_empty(), map::is_flammable(), is_mounted(), Creature::is_player(), bionic_data::is_remote_fueled, visitable< Character >::items_with(), itype_water_clean, m_bad, m_good, m_info, m_mixed, m_neutral, martial_arts_data, Creature::mod_moves(), mod_power_level(), my_bionics, bionic_data::name, lockpicking_open_result::new_furn_type, lockpicking_open_result::new_ter_type, one_in(), lockpicking_open_result::open_message, overmap_buffer, damage_instance::physical(), map::points_in_radius(), pos(), bionic_data::power_activate, bionic::powered, w_point::pressure, primary_weapon(), print_humidity(), print_pressure(), print_temperature(), projectile_attack(), query_yn(), shockwave_data::radius, projectile::range, recalculate_enchantment_cache(), Creature::remove_effect(), reset(), reset_encumbrance(), rl_dist(), rng(), sees(), set_painkiller(), set_power_level(), set_primary_weapon(), set_stim(), explosion_handler::shockwave(), sounds::sound(), projectile::speed, calendar::start_of_cataclysm, string_format(), shockwave_data::stun, behavior::success, t_null, teleport::teleport(), w_point::temperature, overmapbuffer::ter(), units::to_fahrenheit(), units::to_kilojoule(), calendar::turn, map::veh_at(), velocity_units(), VU_WIND, and weight_capacity().

Referenced by npc::activate_bionic_by_id(), add_bionic(), show_bionics_ui(), and npc::use_bionic_by_id().

◆ activate_mutation()

void Character::activate_mutation ( const trait_id mutation)

Definition at line 468 of file mutation.cpp.

469{
470 const mutation_branch &mdata = mut.obj();
471 char_trait_data &tdata = my_mutations[mut];
472 // You can take yourself halfway to Near Death levels of hunger/thirst.
473 // Fatigue can go to Exhausted.
474 if( !can_use_mutation_warn( mut, *this ) ) {
475 return;
476 }
478 tdata.powered = true;
479
480 if( !mut->enchantments.empty() ) {
482 }
483
484 if( mdata.transform ) {
485 const cata::value_ptr<mut_transform> trans = mdata.transform;
486 mod_moves( - trans->moves );
487 switch_mutations( mut, trans->target, trans->active );
488 return;
489 }
490
491 if( mut == trait_WEB_WEAVER ) {
492 g->m.add_field( pos(), fd_web, 1 );
493 add_msg_if_player( _( "You start spinning web with your spinnerets!" ) );
494 } else if( mut == trait_BURROW ) {
495 tdata.powered = false;
496 item burrowing_item( itype_id( "fake_burrowing" ) );
497 invoke_item( &burrowing_item );
498 return; // handled when the activity finishes
499 } else if( mut == trait_SLIMESPAWNER ) {
500 monster *const slime = g->place_critter_around( mtype_id( "mon_player_blob" ), pos(), 1 );
501 if( !slime ) {
502 // Oops, no room to divide!
503 add_msg_if_player( m_bad, _( "You focus, but are too hemmed in to birth a new slimespring!" ) );
504 tdata.powered = false;
505 return;
506 }
508 _( "You focus, and with a pleasant splitting feeling, birth a new slimespring!" ) );
509 slime->friendly = -1;
510 if( one_in( 3 ) ) {
512 //~ Usual enthusiastic slimespring small voices! :D
513 _( "wow! you look just like me! we should look out for each other!" ) );
514 } else if( one_in( 2 ) ) {
515 //~ Usual enthusiastic slimespring small voices! :D
516 add_msg_if_player( m_good, _( "come on, big me, let's go!" ) );
517 } else {
518 //~ Usual enthusiastic slimespring small voices! :D
519 add_msg_if_player( m_good, _( "we're a team, we've got this!" ) );
520 }
521 tdata.powered = false;
522 return;
523 } else if( mut == trait_NAUSEA || mut == trait_VOMITOUS ) {
524 vomit();
525 tdata.powered = false;
526 return;
527 } else if( mut == trait_M_FERTILE ) {
528 spores();
529 tdata.powered = false;
530 return;
531 } else if( mut == trait_M_BLOOM ) {
532 blossoms();
533 tdata.powered = false;
534 return;
535 } else if( mut == trait_M_PROVENANCE ) {
536 spores(); // double trouble!
537 blossoms();
538 tdata.powered = false;
539 return;
540 } else if( mut == trait_SELFAWARE ) {
541 print_health();
542 tdata.powered = false;
543 return;
544 } else if( mut == trait_TREE_COMMUNION ) {
545 tdata.powered = false;
546 if( !overmap_buffer.ter( global_omt_location() ).obj().is_wooded() ) {
547 add_msg_if_player( m_info, _( "You can only do that in a wooded area." ) );
548 return;
549 }
550 // Check for adjacent trees.
551 bool adjacent_tree = false;
552 for( const tripoint &p2 : g->m.points_in_radius( pos(), 1 ) ) {
553 if( g->m.has_flag( "TREE", p2 ) ) {
554 adjacent_tree = true;
555 }
556 }
557 if( !adjacent_tree ) {
558 add_msg_if_player( m_info, _( "You can only do that next to a tree." ) );
559 return;
560 }
561
563 add_msg_if_player( _( "You reach out to the trees with your roots." ) );
564 } else {
566 _( "You lay next to the trees letting your hair roots tangle with the trees." ) );
567 }
568
570
572 const time_duration startup_time = has_trait( trait_ROOTS3 ) ? rng( 15_minutes,
573 30_minutes ) : rng( 60_minutes, 90_minutes );
574 activity.values.push_back( to_turns<int>( startup_time ) );
575 return;
576 } else {
577 const time_duration startup_time = rng( 120_minutes, 180_minutes );
578 activity.values.push_back( to_turns<int>( startup_time ) );
579 return;
580 }
581 } else if( !mdata.spawn_item.is_empty() ) {
582 item tmpitem( mdata.spawn_item );
583 i_add_or_drop( tmpitem );
585 tdata.powered = false;
586 return;
587 } else if( !mdata.ranged_mutation.is_empty() ) {
590 tdata.powered = false;
591 return;
592 }
593}
mutation_collection my_mutations
Traits / mutations of the character.
Definition: character.h:2157
player_activity activity
Definition: character.h:1578
void vomit()
Handles Character vomiting effects.
Definition: character.cpp:7697
void print_health() const
Definition: character.cpp:4219
void blossoms()
Definition: character.cpp:8792
void switch_mutations(const trait_id &switched, const trait_id &target, bool start_powered)
Unset switched mutation and set target mutation instead.
Definition: mutation.cpp:182
void spores()
Definition: character.cpp:8778
bool i_add_or_drop(item &it, int qty=1)
Sets invlet and adds to inventory if possible, drops otherwise, returns true if either succeeded.
Definition: character.cpp:2407
void mutation_spend_resources(const trait_id &mut)
Removes the appropriate costs (NOTE: will reapply mods & recalc sightlines in case of newly activated...
Definition: mutation.cpp:1698
void assign_activity(const activity_id &type, int moves=calendar::INDEFINITELY_LONG, int index=-1, int pos=INT_MIN, const std::string &name="")
Legacy activity assignment, does not work for any activites using the new activity_actor class and ma...
Definition: character.cpp:9191
This class is essentially a copyable unique pointer.
Definition: value_ptr.h:19
int friendly
Definition: monster.h:471
std::vector< int > values
A duration defined as a number of specific time units.
Definition: calendar.h:180
field_type_id fd_web
Definition: field_type.cpp:340
static const activity_id ACT_TREE_COMMUNION("ACT_TREE_COMMUNION")
static const trait_id trait_M_FERTILE("M_FERTILE")
static const trait_id trait_BURROW("BURROW")
static const trait_id trait_SLIMESPAWNER("SLIMESPAWNER")
static const trait_id trait_ROOTS2("ROOTS2")
static const trait_id trait_WEB_WEAVER("WEB_WEAVER")
bool can_use_mutation_warn(const trait_id &mut, const Character &character)
Calls can_use_mutation and if it fails, print a standard message.
Definition: mutation.cpp:1687
static const trait_id trait_M_BLOOM("M_BLOOM")
static const trait_id trait_VOMITOUS("VOMITOUS")
static const trait_id trait_SELFAWARE("SELFAWARE")
static const trait_id trait_NAUSEA("NAUSEA")
static const trait_id trait_M_PROVENANCE("M_PROVENANCE")
static const trait_id trait_TREE_COMMUNION("TREE_COMMUNION")
static const trait_id trait_ROOTS3("ROOTS3")
void fire_ranged_mutation(avatar &you, const item &fake_gun)
Stores fake gun specified by the mutation and starts interactive aiming.
bool powered
Whether the mutation is activated.
Definition: character.h:210
std::string ranged_mutation_message() const
std::string spawn_item_message() const
cata::value_ptr< mut_transform > transform
Definition: mutation.h:153
itype_id spawn_item
The item, if any, spawned by the mutation.
Definition: mutation.h:205
itype_id ranged_mutation
The fake gun, if any, spawned and fired by the ranged mutation.
Definition: mutation.h:243

References _, ACT_TREE_COMMUNION, activity, Creature::add_msg_if_player(), assign_activity(), blossoms(), can_use_mutation_warn(), mutation_branch::enchantments, fd_web, avatar_action::fire_ranged_mutation(), monster::friendly, g, global_omt_location(), has_trait(), i_add_or_drop(), invoke_item(), string_id< T >::is_empty(), itype_id, m_bad, m_good, m_info, Creature::mod_moves(), mtype_id, mutation_spend_resources(), my_mutations, string_id< T >::obj(), one_in(), overmap_buffer, pos(), char_trait_data::powered, print_health(), mutation_branch::ranged_mutation, mutation_branch::ranged_mutation_message(), recalculate_enchantment_cache(), rng(), mutation_branch::spawn_item, mutation_branch::spawn_item_message(), spores(), switch_mutations(), overmapbuffer::ter(), trait_BURROW, trait_M_BLOOM, trait_M_FERTILE, trait_M_PROVENANCE, trait_NAUSEA, trait_ROOTS2, trait_ROOTS3, trait_SELFAWARE, trait_SLIMESPAWNER, trait_TREE_COMMUNION, trait_VOMITOUS, trait_WEB_WEAVER, mutation_branch::transform, player_activity::values, and vomit().

Referenced by show_mutations_ui(), and detail::show_mutations_ui_internal().

◆ active_light()

float Character::active_light ( ) const

Returns character luminosity based on the brightest active item they are carrying.

Definition at line 6309 of file character.cpp.

6310{
6311 float lumination = 0;
6312
6313 int maxlum = 0;
6314 has_item_with( [&maxlum]( const item & it ) {
6315 const int lumit = it.getlight_emit();
6316 if( maxlum < lumit ) {
6317 maxlum = lumit;
6318 }
6319 return false; // continue search, otherwise has_item_with would cancel the search
6320 } );
6321
6322 lumination = static_cast<float>( maxlum );
6323
6324 float mut_lum = 0.0f;
6325 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
6326 if( mut.second.powered ) {
6327 float curr_lum = 0.0f;
6328 for( const auto elem : mut.first->lumination ) {
6329 int coverage = 0;
6330 for( const item &i : worn ) {
6331 if( i.covers( elem.first ) && !i.has_flag( flag_ALLOWS_NATURAL_ATTACKS ) &&
6332 !i.has_flag( flag_SEMITANGIBLE ) &&
6333 !i.has_flag( flag_PERSONAL ) && !i.has_flag( flag_AURA ) ) {
6334 coverage += i.get_coverage();
6335 }
6336 }
6337 curr_lum += elem.second * ( 1 - ( coverage / 100.0f ) );
6338 }
6339 mut_lum += curr_lum;
6340 }
6341 }
6342
6343 lumination = std::max( lumination, mut_lum );
6344
6345 if( lumination < 60 && has_active_bionic( bio_flashlight ) ) {
6346 lumination = 60;
6347 } else if( lumination < 25 && has_artifact_with( AEP_GLOW ) ) {
6348 lumination = 25;
6349 } else if( lumination < 5 && ( has_effect( effect_glowing ) ||
6351 has_effect( effect_glowy_led ) ) ) ) {
6352 lumination = 5;
6353 }
6354 return lumination;
6355}
static const efftype_id effect_glowy_led("glowy_led")
static const bionic_id bio_flashlight("bio_flashlight")
static const std::string flag_SEMITANGIBLE("SEMITANGIBLE")
static const std::string flag_ALLOWS_NATURAL_ATTACKS("ALLOWS_NATURAL_ATTACKS")
static const efftype_id effect_glowing("glowing")
static const std::string flag_AURA("AURA")
static const bionic_id bio_tattoo_led("bio_tattoo_led")
static const std::string flag_PERSONAL("PERSONAL")
virtual bool has_artifact_with(art_effect_passive effect) const
Definition: character.cpp:3212
int getlight_emit() const
How much light (see lightmap.cpp) the item emits (it's assumed to be circular).
Definition: item.cpp:8401
bool has_item_with(const std::function< bool(const item &)> &filter) const
Returns true if any item (including those within a container) matches the filter.
Definition: visitable.cpp:104
@ AEP_GLOW
Definition: enums.h:115

References AEP_GLOW, bio_flashlight, bio_tattoo_led, effect_glowing, effect_glowy_led, flag_ALLOWS_NATURAL_ATTACKS(), flag_AURA(), flag_PERSONAL(), flag_SEMITANGIBLE(), item::getlight_emit(), has_active_bionic(), has_artifact_with(), Creature::has_effect(), visitable< Character >::has_item_with(), my_mutations, and worn.

Referenced by map::apply_character_light(), and character_funcs::fine_detail_vision_mod().

◆ add_addiction()

void Character::add_addiction ( add_type  type,
int  strength 
)

Adds an addiction to the player.

Definition at line 1959 of file suffer.cpp.

1960{
1961 if( type == add_type::NONE ) {
1962 return;
1963 }
1964 time_duration timer = 2_hours;
1965 if( has_trait( trait_ADDICTIVE ) ) {
1966 strength *= 2;
1967 timer = 1_hours;
1968 } else if( has_trait( trait_NONADDICTIVE ) ) {
1969 strength /= 2;
1970 timer = 6_hours;
1971 }
1972 //Update existing addiction
1973 for( auto &i : addictions ) {
1974 if( i.type != type ) {
1975 continue;
1976 }
1977
1978 if( i.sated < 0_turns ) {
1979 i.sated = timer;
1980 } else if( i.sated < 10_minutes ) {
1981 // TODO: Make this variable?
1982 i.sated += timer;
1983 } else {
1984 i.sated += timer / 2;
1985 }
1986 if( i.intensity < MAX_ADDICTION_LEVEL && strength > i.intensity * rng( 2, 5 ) ) {
1987 i.intensity++;
1988 }
1989
1990 add_msg( m_debug, "Updating addiction: %d intensity, %d sated",
1991 i.intensity, to_turns<int>( i.sated ) );
1992
1993 return;
1994 }
1995
1996 // Add a new addiction
1997 const int roll = rng( 0, 100 );
1998 add_msg( m_debug, "Addiction: roll %d vs strength %d", roll, strength );
1999 if( roll < strength ) {
2000 const std::string &type_name = addiction_type_name( type );
2001 add_msg( m_debug, "%s got addicted to %s", disp_name(), type_name );
2002 addictions.emplace_back( type, 1 );
2003 g->events().send<event_type::gains_addiction>( getID(), type );
2004 }
2005}
std::string addiction_type_name(add_type const cur)
Returns the name of an addiction.
Definition: addiction.cpp:253
constexpr int MAX_ADDICTION_LEVEL
Definition: addiction.h:14
std::vector< addiction > addictions
Definition: character.h:1607
character_id getID() const
Definition: character.cpp:494
@ m_debug
Definition: enums.h:271
static const trait_id trait_NONADDICTIVE("NONADDICTIVE")
static const trait_id trait_ADDICTIVE("ADDICTIVE")

References add_msg(), addiction_type_name(), addictions, disp_name(), g, gains_addiction, getID(), has_trait(), m_debug, MAX_ADDICTION_LEVEL, NONE, rng(), trait_ADDICTIVE, trait_NONADDICTIVE, and type.

Referenced by iexamine::flower_poppy(), marloss_common(), and modify_addiction().

◆ add_bionic()

void Character::add_bionic ( const bionic_id b)

Adds a bionic to my_bionics[].

Definition at line 2603 of file bionics.cpp.

2604{
2605 if( has_bionic( b ) ) {
2606 debugmsg( "Tried to install bionic %s that is already installed!", b.c_str() );
2607 return;
2608 }
2609
2610 const units::energy pow_up = b->capacity;
2611 mod_max_power_level( pow_up );
2613 add_msg_if_player( m_good, _( "Increased storage capacity by %i." ),
2614 units::to_kilojoule( pow_up ) );
2615 // Power Storage CBMs are not real bionic units, so return without adding it to my_bionics
2616 return;
2617 }
2618
2619 my_bionics->push_back( bionic( b, get_free_invlet( *my_bionics ) ) );
2620 if( b == bio_tools || b == bio_ears ) {
2621 activate_bionic( my_bionics->back() );
2622 }
2623
2624 for( const bionic_id &inc_bid : b->included_bionics ) {
2625 add_bionic( inc_bid );
2626 }
2627
2628 for( const std::pair<const spell_id, int> &spell_pair : b->learned_spells ) {
2629 const spell_id learned_spell = spell_pair.first;
2630 if( learned_spell->spell_class != trait_id( "NONE" ) ) {
2631 const trait_id spell_class = learned_spell->spell_class;
2632 // spells you learn from a bionic overwrite the opposite spell class.
2633 // for best UX, include those spell classes in "canceled_mutations"
2634 if( !has_trait( spell_class ) ) {
2635 set_mutation( spell_class );
2636 on_mutation_gain( spell_class );
2637 add_msg_if_player( spell_class->desc() );
2638 }
2639 }
2640 if( !magic->knows_spell( learned_spell ) ) {
2641 magic->learn_spell( learned_spell, *this, true );
2642 }
2643 spell &known_spell = magic->get_spell( learned_spell );
2644 // spells you learn from installing a bionic upgrade spells you know if they are the same
2645 if( known_spell.get_level() < spell_pair.second ) {
2646 known_spell.set_level( spell_pair.second );
2647 }
2648 }
2649
2652 if( !b->enchantments.empty() ) {
2654 }
2655}
static const bionic_id bio_power_storage("bio_power_storage")
static const bionic_id bio_power_storage_mkII("bio_power_storage_mkII")
char get_free_invlet(bionic_collection &bionics)
Definition: bionics_ui.cpp:177
void mod_max_power_level(const units::energy &npower_max)
Definition: character.cpp:1936
bool activate_bionic(bionic &bio, bool eff_only=false)
Handles bionic activation effects of the entered bionic, returns if anything activated.
Definition: bionics.cpp:589
void on_mutation_gain(const trait_id &mid)
Called when a mutation is gained.
Definition: character.cpp:9895
bool has_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id.
Definition: character.cpp:1814
void add_bionic(const bionic_id &b)
Adds a bionic to my_bionics[].
Definition: bionics.cpp:2603
void recalc_sight_limits()
Modifies the player's sight values Must be called when any of the following change: This must be call...
Definition: character.cpp:1629
void set_mutation(const trait_id &)
Add or removes a mutation on the player, but does not trigger mutation loss/gain effects.
Definition: mutation.cpp:152
pimpl< known_magic > magic
Definition: character.h:1485
trait_id spell_class
Definition: magic.h:236
Definition: magic.h:286
int get_level() const
Definition: magic.cpp:1034
void set_level(int nlevel)
Definition: magic.cpp:612
#define debugmsg(...)
Debug message of level DL::Error and class DC::DebugMsg, also includes the source file name and line,...
Definition: debug.h:74
constexpr double b
Definition: magic.cpp:1031
std::string desc() const

References _, activate_bionic(), add_bionic(), Creature::add_msg_if_player(), b, bio_ears, bio_power_storage, bio_power_storage_mkII, bio_tools, debugmsg, mutation_branch::desc(), get_free_invlet(), spell::get_level(), has_bionic(), has_trait(), m_good, magic, mod_max_power_level(), my_bionics, on_mutation_gain(), recalc_sight_limits(), recalculate_enchantment_cache(), reset_encumbrance(), spell::set_level(), set_mutation(), spell_type::spell_class, and units::to_kilojoule().

Referenced by add_bionic(), bionics_install_failure(), avatar::create(), deactivate_bionic(), player::load(), perform_install(), and npc::randomize().

◆ add_known_trap()

void Character::add_known_trap ( const tripoint pos,
const trap t 
)

Definition at line 10254 of file character.cpp.

10255{
10256 const tripoint p = get_map().getabs( pos );
10257 if( t.is_null() ) {
10258 known_traps.erase( p );
10259 } else {
10260 // TODO: known_traps should map to a trap_str_id
10261 known_traps[p] = t.id.str();
10262 }
10263}
trap_map known_traps
Definition: character.h:2148
tripoint getabs(const tripoint &p) const
Translates local (to this map) coordinates of a square to global absolute coordinates.
Definition: map.cpp:8406
const std::string & str() const
Returns the identifier as plain std::string.
Definition: string_id.h:255
bool is_null() const
Whether this is the null-traps, aka no trap at all.
Definition: trap.cpp:245
trap_str_id id
Definition: trap.h:87

References get_map(), map::getabs(), trap::id, trap::is_null(), known_traps, pos(), and string_id< T >::str().

Referenced by vehicle::handle_trap(), place_and_add_as_known(), and character_funcs::search_surroundings().

◆ add_miss_reason()

void Character::add_miss_reason ( const std::string &  reason,
unsigned int  weight 
)

Adds a reason for why the player would miss a melee attack.

To possibly be messaged to the player when he misses a melee attack.

Parameters
reasonA message for the player that gives a reason for him missing.
weightThe weight used when choosing what reason to pick when the player misses.

Definition at line 378 of file melee.cpp.

379{
380 melee_miss_reasons.add( reason, weight );
381
382}
struct weighted_int_list< std::string > melee_miss_reasons
Definition: character.h:2273

References melee_miss_reasons.

Referenced by temperature_effect::apply(), eff_fun_hallu(), get_miss_reason(), hardcoded_effects(), process_one_effect(), reset_stats(), and suffer_in_sunlight().

◆ add_morale()

void Character::add_morale ( const morale_type type,
int  bonus,
int  max_bonus = 0,
const time_duration duration = 1_hours,
const time_duration decay_start = 30_minutes,
bool  capped = false,
const itype item_type = nullptr 
)

Definition at line 9093 of file character.cpp.

9096{
9097 if( item_type != nullptr ) {
9098 morale->add( type, bonus, max_bonus, duration, decay_start, capped, *item_type );
9099 } else {
9100 morale->add( type, bonus, max_bonus, duration, decay_start, capped );
9101 }
9102}
pimpl< player_morale > morale
Definition: character.h:2210

References morale, and type.

Referenced by addict_effect(), apply_persistent_morale(), apply_wetness_morale(), iuse::artifact(), iuse::bell(), iuse::blech(), debug_menu::character_edit_menu(), iuse::datura(), monster::die(), avatar::do_read(), iuse::einktabletpc(), npc::finish_read(), ranged::fire_gun(), activity_handlers::generic_game_do_turn(), activity_handlers::haircut_finish(), hardcoded_effects(), marloss_add(), marloss_common(), activity_handlers::meditate_finish(), modify_morale(), spell_effect::morale(), iuse::mycus(), iuse::plantblech(), iuse::play_music(), activity_handlers::play_with_pet_finish(), iuse::portable_game(), game::process_artifact(), process_bionic(), firestarter_actor::resolve_firestarter_use(), set_up_butchery_activity(), activity_handlers::shaving_finish(), game::start_game(), suffer_feral_kill_withdrawl(), suffer_from_chemimbalance(), suffer_from_other_mutations(), suffer_from_schizophrenia(), suffer_while_awake(), activity_handlers::tree_communion_do_turn(), update_bodytemp(), enzlave_actor::use(), musical_instrument_actor::use(), mutagen_actor::use(), mutagen_iv_actor::use(), activity_handlers::vibe_do_turn(), activity_handlers::vibe_finish(), and avatar::vomit().

◆ addiction_level()

int Character::addiction_level ( add_type  type) const

Returns the intensity of the specified addiction.

Definition at line 2028 of file suffer.cpp.

2029{
2030 auto iter = std::find_if( addictions.begin(), addictions.end(),
2031 [type]( const addiction & ad ) {
2032 return ad.type == type;
2033 } );
2034 return iter != addictions.end() ? iter->intensity : 0;
2035}

References addictions, and type.

Referenced by iuse::ecig(), mend(), process_one_effect(), and iuse::smoking().

◆ adjust_for_focus()

int Character::adjust_for_focus ( int  amount) const

Definition at line 9938 of file character.cpp.

9939{
9940 int effective_focus = focus_pool;
9941 if( has_trait( trait_FASTLEARNER ) ) {
9942 effective_focus += 15;
9943 }
9944 if( has_active_bionic( bio_memory ) ) {
9945 effective_focus += 10;
9946 }
9947 if( has_trait( trait_SLOWLEARNER ) ) {
9948 effective_focus -= 15;
9949 }
9950 effective_focus += ( get_int() - get_option<int>( "INT_BASED_LEARNING_BASE_VALUE" ) ) *
9951 get_option<int>( "INT_BASED_LEARNING_FOCUS_ADJUSTMENT" );
9952 double tmp = amount * ( effective_focus / 100.0 );
9953 return roll_remainder( tmp );
9954}
static const trait_id trait_FASTLEARNER("FASTLEARNER")
static const bionic_id bio_memory("bio_memory")
static const trait_id trait_SLOWLEARNER("SLOWLEARNER")
int focus_pool
Definition: character.h:1598
virtual int get_int() const
Definition: character.cpp:4100

References bio_memory, focus_pool, get_int(), has_active_bionic(), has_trait(), roll_remainder(), trait_FASTLEARNER, and trait_SLOWLEARNER.

Referenced by spell::casting_exp(), avatar::do_read(), and practice().

◆ age()

int Character::age ( ) const

Definition at line 6793 of file character.cpp.

6794{
6795 int years_since_cataclysm = to_turns<int>( calendar::turn - calendar::turn_zero ) /
6796 to_turns<int>( calendar::year_length() );
6797 return init_age + years_since_cataclysm;
6798}
int init_age
age in years at character creation
Definition: character.h:2142
time_duration year_length()
Definition: calendar.cpp:461
const time_point turn_zero
Represents time point 0.
Definition: calendar.cpp:26

References init_age, calendar::turn, calendar::turn_zero, and calendar::year_length().

Referenced by age_string(), and set_base_age().

◆ age_string()

std::string Character::age_string ( ) const

Definition at line 6800 of file character.cpp.

6801{
6802 //~ how old the character is in years. try to limit number of characters to fit on the screen
6803 std::string unformatted = _( "%d years" );
6804 return string_format( unformatted, age() );
6805}
int age() const
Definition: character.cpp:6793

References _, age(), and string_format().

Referenced by draw_stats_info(), and draw_stats_tab().

◆ all_items_with_flag()

std::vector< const item * > Character::all_items_with_flag ( const std::string &  flag) const

All items that have the given flag (item::has_flag).

Definition at line 9596 of file character.cpp.

9597{
9598 return items_with( [&flag]( const item & it ) {
9599 return it.has_flag( flag );
9600 } );
9601}

References item::has_flag(), and visitable< Character >::items_with().

Referenced by iexamine::choose_fertilizer(), iexamine::dimensional_portal(), has_fire(), and use_fire().

◆ allergy_type()

morale_type Character::allergy_type ( const item food) const

Returns allergy type or MORALE_NULL if not allergic for this character.

Definition at line 619 of file consumption.cpp.

620{
621 using allergy_tuple = std::tuple<trait_id, std::string, morale_type>;
622 static const std::array<allergy_tuple, 8> allergy_tuples = {{
629 }
630 };
631
632 for( const auto &tp : allergy_tuples ) {
633 if( has_trait( std::get<0>( tp ) ) &&
634 food.has_flag( std::get<1>( tp ) ) ) {
635 return std::get<2>( tp );
636 }
637 }
638
639 return MORALE_NULL;
640}
static const std::string flag_ALLERGEN_MILK("ALLERGEN_MILK")
static const std::string flag_ALLERGEN_VEGGY("ALLERGEN_VEGGY")
static const std::string flag_ALLERGEN_JUNK("ALLERGEN_JUNK")
static const std::string flag_ALLERGEN_FRUIT("ALLERGEN_FRUIT")
static const trait_id trait_ANTIWHEAT("ANTIWHEAT")
static const trait_id trait_ANTIJUNK("ANTIJUNK")
static const trait_id trait_VEGETARIAN("VEGETARIAN")
static const trait_id trait_LACTOSE("LACTOSE")
static const std::string flag_ALLERGEN_WHEAT("ALLERGEN_WHEAT")
static const std::string flag_ALLERGEN_MEAT("ALLERGEN_MEAT")
static const trait_id trait_MEATARIAN("MEATARIAN")
static const trait_id trait_ANTIFRUIT("ANTIFRUIT")
const morale_type MORALE_MEATARIAN("morale_meatarian")
const morale_type MORALE_ANTIJUNK("morale_antijunk")
const morale_type MORALE_ANTIWHEAT("morale_antiwheat")
const morale_type MORALE_ANTIFRUIT("morale_antifruit")
const morale_type MORALE_LACTOSE("morale_lactose")
const morale_type MORALE_VEGETARIAN("morale_vegetarian")
const morale_type MORALE_NULL("morale_null")

References flag_ALLERGEN_FRUIT(), flag_ALLERGEN_JUNK(), flag_ALLERGEN_MEAT(), flag_ALLERGEN_MILK(), flag_ALLERGEN_VEGGY(), flag_ALLERGEN_WHEAT(), item::has_flag(), has_trait(), MORALE_ANTIFRUIT, MORALE_ANTIJUNK, MORALE_ANTIWHEAT, MORALE_LACTOSE, MORALE_MEATARIAN, MORALE_NULL, MORALE_VEGETARIAN, trait_ANTIFRUIT, trait_ANTIJUNK, trait_ANTIWHEAT, trait_LACTOSE, trait_MEATARIAN, and trait_VEGETARIAN.

Referenced by item::color_in_inventory(), item::food_info(), modify_morale(), and will_eat().

◆ allocated_invlets()

invlets_bitset Character::allocated_invlets ( ) const

Only use for UI things.

Returns all invlets that are currently used in the player inventory, the weapon slot and the worn items.

Definition at line 2494 of file character.cpp.

2495{
2497
2498 const item &weapon = primary_weapon();
2499 invlets.set( weapon.invlet );
2500 for( const auto &w : worn ) {
2501 invlets.set( w.invlet );
2502 }
2503
2504 invlets[0] = false;
2505
2506 return invlets;
2507}
inventory inv
Definition: character.h:1581
invlets_bitset allocated_invlets() const
Definition: inventory.cpp:1261
std::bitset< std::numeric_limits< char >::max()> invlets_bitset
Definition: inventory.h:36

References inventory::allocated_invlets(), inv, item::invlet, primary_weapon(), and worn.

Referenced by inventory::assign_empty_invlet(), game_menus::inv::common(), and i_add().

◆ amount_of_storage_bionics()

std::pair< int, int > Character::amount_of_storage_bionics ( ) const

Returns amount of Storage CBMs in the corpse.

Definition at line 2699 of file bionics.cpp.

2700{
2702
2703 // exclude amount of power capacity obtained via non-power-storage CBMs
2704 for( const bionic &it : *my_bionics ) {
2705 lvl -= it.info().capacity;
2706 }
2707
2708 std::pair<int, int> results( 0, 0 );
2709 if( lvl <= 0_kJ ) {
2710 return results;
2711 }
2712
2713 const units::energy pow_mkI = bio_power_storage->capacity;
2715
2716 while( lvl >= std::min( pow_mkI, pow_mkII ) ) {
2717 if( one_in( 2 ) ) {
2718 if( lvl >= pow_mkI ) {
2719 results.first++;
2720 lvl -= pow_mkI;
2721 }
2722 } else {
2723 if( lvl >= pow_mkII ) {
2724 results.second++;
2725 lvl -= pow_mkII;
2726 }
2727 }
2728 }
2729 return results;
2730}
units::energy get_max_power_level() const
Definition: character.cpp:1909
units::energy capacity
Power bank size.
Definition: bionics.h:49

References bio_power_storage, bio_power_storage_mkII, bionic_data::capacity, get_max_power_level(), my_bionics, and one_in().

Referenced by place_corpse().

◆ amount_worn()

int Character::amount_worn ( const itype_id id) const

Returns the amount of item ‘type’ that is currently worn.

Definition at line 2187 of file character.cpp.

2188{
2189 int amount = 0;
2190 for( auto &elem : worn ) {
2191 if( elem.typeId() == id ) {
2192 ++amount;
2193 }
2194 }
2195 return amount;
2196}

References worn.

Referenced by can_wear().

◆ apply_damage()

void Character::apply_damage ( Creature source,
bodypart_id  hurt,
int  dam,
bool  bypass_med = false 
)
overridevirtual

Actually hurt the player, hurts a body_part directly, no armor reduction.

Implements Creature.

Definition at line 8402 of file character.cpp.

8404{
8406 // don't do any more damage if we're already dead
8407 // Or if we're debugging and don't want to die
8408 return;
8409 }
8410
8411 if( hurt == bodypart_id( "num_bp" ) ) {
8412 debugmsg( "Wacky body part hurt!" );
8413 hurt = bodypart_id( "torso" );
8414 }
8415
8416 mod_pain( dam / 2 );
8417
8418 const bodypart_id &part_to_damage = hurt->main_part;
8419
8420 const int dam_to_bodypart = std::min( dam, get_part_hp_cur( part_to_damage ) );
8421
8422 mod_part_hp_cur( part_to_damage, - dam_to_bodypart );
8424
8425 const item &weapon = primary_weapon();
8426 if( !weapon.is_null() && !as_player()->can_wield( weapon ).success() &&
8427 can_unwield( weapon ).success() ) {
8428 add_msg_if_player( _( "You are no longer able to wield your %s and drop it!" ),
8429 weapon.display_name() );
8431 i_rem( &weapon );
8432 }
8433 if( has_effect( effect_mending, part_to_damage->token ) ) {
8434 effect &e = get_effect( effect_mending, part_to_damage->token );
8435 float remove_mend = dam / 20.0f;
8436 e.mod_duration( -e.get_max_duration() * remove_mend );
8437 }
8438
8439 if( dam > get_painkiller() ) {
8440 on_hurt( source );
8441 }
8442
8443 if( is_dead_state() ) {
8444 // if the player killed himself, add it to the kill count list
8445 if( !is_npc() && !killer && source == g->u.as_character() ) {
8447 get_name() );
8448 }
8449 set_killer( source );
8450 }
8451
8452 if( !bypass_med ) {
8453 // remove healing effects if damaged
8454 int remove_med = roll_remainder( dam / 5.0f );
8455 if( remove_med > 0 && has_effect( effect_bandaged, part_to_damage->token ) ) {
8456 remove_med -= reduce_healing_effect( effect_bandaged, remove_med, part_to_damage );
8457 }
8458 if( remove_med > 0 && has_effect( effect_disinfected, part_to_damage->token ) ) {
8459 reduce_healing_effect( effect_disinfected, remove_med, part_to_damage );
8460 }
8461 }
8462}
void put_into_vehicle_or_drop(Character &c, item_drop_reason, const std::list< item > &items)
static const trait_id trait_DEBUG_NODMG("DEBUG_NODMG")
static const efftype_id effect_bandaged("bandaged")
static const efftype_id effect_disinfected("disinfected")
static const efftype_id effect_mending("mending")
void mod_pain(int npain) override
Modifies a pain value by player traits before passing it to Creature::mod_pain()
Definition: character.cpp:764
int get_painkiller() const
Returns intensity of painkillers
Definition: character.cpp:9809
item i_rem(int pos)
Remove a specific item from player possession.
Definition: character.cpp:2372
int reduce_healing_effect(const efftype_id &eff_id, int remove_med, const bodypart_id &hurt)
Reduce healing effect intensity, return initial intensity of the effect.
Definition: character.cpp:8621
void on_hurt(Creature *source, bool disturb=true)
Handles effects that happen when the player is damaged and aware of the fact.
Definition: character.cpp:8694
ret_val< bool > can_wield(const item &it) const
Check whether character is capable of wielding given item.
Definition: character.cpp:3089
ret_val< bool > can_unwield(const item &it) const
Check whether character is capable of unwielding given item.
Definition: character.cpp:3125
bool is_dead_state() const override
Returns true if the character should be dead.
Definition: character.cpp:499
std::string get_name() const override
Definition: character.cpp:5997
void mod_part_hp_cur(const bodypart_id &id, int mod)
Definition: creature.cpp:1636
int get_part_hp_cur(const bodypart_id &id) const
Definition: creature.cpp:1606
virtual player * as_player()
Definition: creature.h:122
void set_killer(Creature *killer)
Definition: creature.cpp:1471
virtual bool is_npc() const
Definition: creature.h:98
Creature * killer
Definition: creature.h:812
Definition: effect.h:161
void mod_duration(const time_duration &dur, bool alert=false)
Mods the duration, capping at max_duration if it exists.
Definition: effect.cpp:821
time_duration get_max_duration() const
Returns the maximum duration of an effect.
Definition: effect.cpp:801
void send(const cata::event &) const
Definition: event_bus.cpp:58
@ character_takes_damage
@ character_kills_character
event_bus & get_event_bus()
Definition: game.cpp:12086

References _, Creature::add_msg_if_player(), Creature::as_player(), can_unwield(), can_wield(), character_kills_character, character_takes_damage, debugmsg, effect_bandaged, effect_disinfected, effect_mending, g, Creature::get_effect(), get_event_bus(), effect::get_max_duration(), get_name(), get_painkiller(), Creature::get_part_hp_cur(), get_player_character(), getID(), Creature::has_effect(), has_trait(), i_rem(), is_dead_state(), Creature::is_npc(), Creature::killer, effect::mod_duration(), mod_pain(), Creature::mod_part_hp_cur(), on_hurt(), primary_weapon(), put_into_vehicle_or_drop(), reduce_healing_effect(), roll_remainder(), event_bus::send(), Creature::set_killer(), behavior::success, trait_DEBUG_NODMG, and tumbling.

Referenced by activate_bionic(), iuse::blech(), cough(), debug_menu::debug(), do_damage_for_bionic_failure(), eff_fun_bleed(), eff_fun_fungus(), iuse::ehandcuffs(), game::find_or_make_stairs(), heal_actor::finish_using(), iexamine::flower_cactus(), iexamine::flower_poppy(), game::handle_action(), start_location::handle_heli_crash(), hardcoded_effects(), knock_back_to(), activity_handlers::operation_do_turn(), process_one_effect(), suffer_from_sunburn(), suffer_water_damage(), and suffer_while_underwater().

◆ apply_mods()

void Character::apply_mods ( const trait_id mut,
bool  add_remove 
)
protected

Applies stat mods to character.

Definition at line 204 of file mutation.cpp.

205{
206 int sign = add_remove ? 1 : -1;
207 int str_change = get_mod( mut, "STR" );
208 str_max += sign * str_change;
209 per_max += sign * get_mod( mut, "PER" );
210 dex_max += sign * get_mod( mut, "DEX" );
211 int_max += sign * get_mod( mut, "INT" );
212
213 if( str_change != 0 ) {
214 recalc_hp();
215 }
216}
void recalc_hp()
Recalculates HP after a change to max strength.
Definition: character.cpp:1582
int get_mod(const trait_id &mut, const std::string &arg) const
Retrieves a stat mod of a mutation.
Definition: mutation.cpp:193

References dex_max, get_mod(), int_max, per_max, recalc_hp(), and str_max.

Referenced by deactivate_mutation(), mutation_effect(), mutation_loss_effect(), mutation_spend_resources(), and suffer_mutation_power().

◆ apply_persistent_morale()

void Character::apply_persistent_morale ( )

Ensures persistent morale effects are up-to-date.

Definition at line 9008 of file character.cpp.

9009{
9010 // Hoarders get a morale penalty if they're not carrying a full inventory.
9011 if( has_trait( trait_HOARDER ) ) {
9012 int pen = ( volume_capacity() - volume_carried() ) / 125_ml;
9013 if( pen > 70 ) {
9014 pen = 70;
9015 }
9016 if( pen <= 0 ) {
9017 pen = 0;
9018 }
9019 if( has_effect( effect_took_xanax ) ) {
9020 pen = pen / 7;
9021 } else if( has_effect( effect_took_prozac ) ) {
9022 pen = pen / 2;
9023 }
9024 if( pen > 0 ) {
9025 add_morale( MORALE_PERM_HOARDER, -pen, -pen, 1_minutes, 1_minutes, true );
9026 }
9027 }
9028 // Nomads get a morale penalty if they stay near the same overmap tiles too long.
9030 const tripoint_abs_omt ompos = global_omt_location();
9031 float total_time = 0;
9032 // Check how long we've stayed in any overmap tile within 5 of us.
9033 const int max_dist = 5;
9034 for( const tripoint_abs_omt &pos : points_in_radius( ompos, max_dist ) ) {
9035 const float dist = rl_dist( ompos, pos );
9036 if( dist > max_dist ) {
9037 continue;
9038 }
9039 const auto iter = overmap_time.find( pos.xy() );
9040 if( iter == overmap_time.end() ) {
9041 continue;
9042 }
9043 // Count time in own tile fully, tiles one away as 4/5, tiles two away as 3/5, etc.
9044 total_time += to_moves<float>( iter->second ) * ( max_dist - dist ) / max_dist;
9045 }
9046 // Characters with higher tiers of Nomad suffer worse morale penalties, faster.
9047 int max_unhappiness;
9048 float min_time, max_time;
9049 if( has_trait( trait_NOMAD ) ) {
9050 max_unhappiness = 20;
9051 min_time = to_moves<float>( 2_days );
9052 max_time = to_moves<float>( 4_days );
9053 } else if( has_trait( trait_NOMAD2 ) ) {
9054 max_unhappiness = 40;
9055 min_time = to_moves<float>( 1_days );
9056 max_time = to_moves<float>( 2_days );
9057 } else { // traid_NOMAD3
9058 max_unhappiness = 60;
9059 min_time = to_moves<float>( 12_hours );
9060 max_time = to_moves<float>( 1_days );
9061 }
9062 // The penalty starts at 1 at min_time and scales up to max_unhappiness at max_time.
9063 const float t = ( total_time - min_time ) / ( max_time - min_time );
9064 const int pen = std::ceil( lerp_clamped( 0, max_unhappiness, t ) );
9065 if( pen > 0 ) {
9066 add_morale( MORALE_PERM_NOMAD, -pen, -pen, 1_minutes, 1_minutes, true );
9067 }
9068 }
9069
9070 if( has_trait( trait_PROF_FOODP ) ) {
9071 // Loosing your face is distressing
9072 if( !( is_wearing( itype_id( "foodperson_mask" ) ) ||
9073 is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) {
9074 add_morale( MORALE_PERM_NOFACE, -20, -20, 1_minutes, 1_minutes, true );
9075 } else if( is_wearing( itype_id( "foodperson_mask" ) ) ||
9076 is_wearing( itype_id( "foodperson_mask_on" ) ) ) {
9078 }
9079
9080 if( is_wearing( itype_id( "foodperson_mask_on" ) ) ) {
9081 add_morale( MORALE_PERM_FPMODE_ON, 10, 10, 1_minutes, 1_minutes, true );
9082 } else {
9084 }
9085 }
9086}
constexpr T lerp_clamped(const T &min, const T &max, float t)
Linear interpolation with t clamped to [0, 1].
Definition: cata_utility.h:166
static const efftype_id effect_took_prozac("took_prozac")
static const trait_id trait_PROF_FOODP("PROF_FOODP")
static const trait_id trait_HOARDER("HOARDER")
static const trait_id trait_NOMAD2("NOMAD2")
static const trait_id trait_NOMAD3("NOMAD3")
static const trait_id trait_NOMAD("NOMAD")
static const efftype_id effect_took_xanax("took_xanax")
units::volume volume_capacity() const
Definition: character.cpp:2670
std::unordered_map< point_abs_omt, time_duration > overmap_time
Amount of time the player has spent in each overmap tile.
Definition: character.h:2289
units::volume volume_carried() const
Definition: character.cpp:2542
void add_morale(const morale_type &type, int bonus, int max_bonus=0, const time_duration &duration=1_hours, const time_duration &decay_start=30_minutes, bool capped=false, const itype *item_type=nullptr)
Definition: character.cpp:9093
void rem_morale(const morale_type &type)
Definition: character.cpp:9114
bool is_wearing(const item &itm) const
Returns true if the player is wearing the item.
Definition: character.cpp:3234
tripoint_range< Tripoint > points_in_radius(const Tripoint &center, const int radius, const int radiusz=0)
Definition: map_iterator.h:125
const morale_type MORALE_PERM_FPMODE_ON("morale_perm_fpmode_on")
const morale_type MORALE_PERM_HOARDER("morale_perm_hoarder")
const morale_type MORALE_PERM_NOMAD("morale_perm_nomad")
const morale_type MORALE_PERM_NOFACE("morale_perm_noface")
constexpr point xy() const
Definition: point.h:206

References add_morale(), effect_took_prozac, effect_took_xanax, global_omt_location(), Creature::has_effect(), has_trait(), is_wearing(), itype_id, lerp_clamped(), MORALE_PERM_FPMODE_ON, MORALE_PERM_HOARDER, MORALE_PERM_NOFACE, MORALE_PERM_NOMAD, overmap_time, points_in_radius(), pos(), rem_morale(), rl_dist(), trait_HOARDER, trait_NOMAD, trait_NOMAD2, trait_NOMAD3, trait_PROF_FOODP, volume_capacity(), volume_carried(), and tripoint::xy().

Referenced by debug_menu::character_edit_menu(), check_and_recover_morale(), avatar::create(), and update_morale().

◆ apply_skill_boost()

void Character::apply_skill_boost ( )
private

Applies skill-based boosts to stats.

Definition at line 3568 of file character.cpp.

3569{
3570 for( const skill_boost &boost : skill_boost::get_all() ) {
3571 // For migration, reset previously applied bonus.
3572 // Remove after 0.E or so.
3573 const std::string bonus_name = boost.stat() + std::string( "_bonus" );
3574 std::string previous_bonus = get_value( bonus_name );
3575 if( !previous_bonus.empty() ) {
3576 if( boost.stat() == "str" ) {
3577 str_max -= atoi( previous_bonus.c_str() );
3578 } else if( boost.stat() == "dex" ) {
3579 dex_max -= atoi( previous_bonus.c_str() );
3580 } else if( boost.stat() == "int" ) {
3581 int_max -= atoi( previous_bonus.c_str() );
3582 } else if( boost.stat() == "per" ) {
3583 per_max -= atoi( previous_bonus.c_str() );
3584 }
3585 remove_value( bonus_name );
3586 }
3587 // End migration code
3588 int skill_total = 0;
3589 for( const std::string &skill_str : boost.skills() ) {
3590 skill_total += get_skill_level( skill_id( skill_str ) );
3591 }
3592 mod_stat( boost.stat(), boost.calc_bonus( skill_total ) );
3593 if( boost.stat() == "str" ) {
3594 recalc_hp();
3595 }
3596 }
3597}
void mod_stat(const std::string &stat, float modifier) override
Definition: character.cpp:546
int get_skill_level(const skill_id &ident) const
Definition: character.cpp:3349
void remove_value(const std::string &key)
Definition: creature.cpp:1376
static const std::vector< skill_boost > & get_all()
Definition: skill_boost.cpp:15

References dex_max, skill_boost::get_all(), get_skill_level(), Creature::get_value(), int_max, mod_stat(), per_max, recalc_hp(), Creature::remove_value(), skill_id, and str_max.

Referenced by reset_stats().

◆ apply_wetness_morale()

void Character::apply_wetness_morale ( int  temperature)

Recalculates morale penalty/bonus from wetness based on mutations, equipment and temperature.

Definition at line 1874 of file suffer.cpp.

1875{
1876 // First, a quick check if we have any wetness to calculate morale from
1877 // Faster than checking all worn items for friendliness
1878 if( !std::any_of( body_wetness.begin(), body_wetness.end(),
1879 []( const int w ) {
1880 return w != 0;
1881} ) ) {
1882 return;
1883 }
1884
1885 // Normalize temperature to [-1.0,1.0]
1886 temperature = std::max( 0, std::min( 100, temperature ) );
1887 const double global_temperature_mod = -1.0 + ( 2.0 * temperature / 100.0 );
1888
1889 int total_morale = 0;
1890 const auto wet_friendliness = exclusive_flag_coverage( "WATER_FRIENDLY" );
1891 for( const body_part bp : all_body_parts ) {
1892 // Sum of body wetness can go up to 103
1893 const int part_drench = body_wetness[bp];
1894 if( part_drench == 0 ) {
1895 continue;
1896 }
1897
1898 const auto &part_arr = mut_drench[bp];
1899 const int part_ignored = part_arr[WT_IGNORED];
1900 const int part_neutral = part_arr[WT_NEUTRAL];
1901 const int part_good = part_arr[WT_GOOD];
1902
1903 if( part_ignored >= part_drench ) {
1904 continue;
1905 }
1906
1907 int bp_morale = 0;
1908 const bool is_friendly = wet_friendliness.test( bp );
1909 const int effective_drench = part_drench - part_ignored;
1910 if( is_friendly ) {
1911 // Using entire bonus from mutations and then some "human" bonus
1912 bp_morale = std::min( part_good, effective_drench ) + effective_drench / 2;
1913 } else if( effective_drench < part_good ) {
1914 // Positive or 0
1915 // Won't go higher than part_good / 2
1916 // Wet slime/scale doesn't feel as good when covered by wet rags/fur/kevlar
1917 bp_morale = std::min( effective_drench, part_good - effective_drench );
1918 } else if( effective_drench > part_good + part_neutral ) {
1919 // This one will be negative
1920 bp_morale = part_good + part_neutral - effective_drench;
1921 }
1922
1923 // Clamp to [COLD,HOT] and cast to double
1924 const double part_temperature =
1925 std::min( BODYTEMP_HOT, std::max( BODYTEMP_COLD, temp_cur[bp] ) );
1926 // 0.0 at COLD, 1.0 at HOT
1927 const double part_mod = ( part_temperature - BODYTEMP_COLD ) /
1929 // Average of global and part temperature modifiers, each in range [-1.0, 1.0]
1930 double scaled_temperature = ( global_temperature_mod + part_mod ) / 2;
1931
1932 if( bp_morale < 0 ) {
1933 // Damp, hot clothing on hot skin feels bad
1934 scaled_temperature = std::fabs( scaled_temperature );
1935 }
1936
1937 // For an unmutated human swimming in deep water, this will add up to:
1938 // +26 when hot in 100% water friendly clothing
1939 // -52 when cold/hot in 100% unfriendly clothing
1940 total_morale += static_cast<int>( bp_morale * ( 1.0 + scaled_temperature ) / 4.0 );
1941 }
1942
1943 if( total_morale == 0 ) {
1944 return;
1945 }
1946
1947 int morale_effect = total_morale / 8;
1948 if( morale_effect == 0 ) {
1949 if( total_morale > 0 ) {
1950 morale_effect = 1;
1951 } else {
1952 morale_effect = -1;
1953 }
1954 }
1955 // 61_seconds because decay is applied in 1_minutes increments
1956 add_morale( MORALE_WET, morale_effect, total_morale, 61_seconds, 61_seconds, true );
1957}
constexpr std::array< body_part, 12 > all_body_parts
Contains all valid body_part values in the order they are defined in.
Definition: bodypart.h:83
body_part
Definition: bodypart.h:40
body_part_set exclusive_flag_coverage(const std::string &flag) const
Bitset of all the body parts covered only with items with flag (or nothing)
Definition: character.cpp:4068
std::array< std::array< int, NUM_WATER_TOLERANCE >, num_bp > mut_drench
Definition: character.h:860
const morale_type MORALE_WET("morale_wet")
quantity< V, U > fabs(quantity< V, U > q)
Definition: units_def.h:136
quantity< int, temperature_in_millidegree_celsius_tag > temperature
static constexpr int BODYTEMP_COLD
Do not change this value, it is an arbitrary anchor on which other calculations are made.
Definition: weather.h:34
static constexpr int BODYTEMP_HOT
Level 2 hotness.
Definition: weather.h:38

References add_morale(), all_body_parts, body_wetness, BODYTEMP_COLD, BODYTEMP_HOT, exclusive_flag_coverage(), units::fabs(), MORALE_WET, mut_drench, temp_cur, WT_GOOD, WT_IGNORED, and WT_NEUTRAL.

Referenced by game::do_turn().

◆ armor_absorb()

bool Character::armor_absorb ( damage_unit du,
item armor 
)

Reduces and mutates du, prints messages about armor taking damage.

Returns
true if the armor was completely destroyed (and the item must be deleted).

Definition at line 8158 of file character.cpp.

8159{
8160 if( rng( 1, 100 ) > armor.get_coverage() ) {
8161 return false;
8162 }
8163
8164 // TODO: add some check for power armor
8165 armor.mitigate_damage( du );
8166
8167 // We want armor's own resistance to this type, not the resistance it grants
8168 const int armors_own_resist = armor.damage_resist( du.type, true );
8169 if( armors_own_resist > 1000 ) {
8170 // This is some weird type that doesn't damage armors
8171 return false;
8172 }
8173
8174 // Scale chance of article taking damage based on the number of parts it covers.
8175 // This represents large articles being able to take more punishment
8176 // before becoming ineffective or being destroyed.
8177 const int num_parts_covered = armor.get_covered_body_parts().count();
8178 if( !one_in( num_parts_covered ) ) {
8179 return false;
8180 }
8181
8182 // Don't damage armor as much when bypassed by armor piercing
8183 // Most armor piercing damage comes from bypassing armor, not forcing through
8184 const int raw_dmg = du.amount * std::min( 1.0f, du.damage_multiplier );
8185 if( raw_dmg > armors_own_resist ) {
8186 // If damage is above armor value, the chance to avoid armor damage is
8187 // 50% + 50% * 1/dmg
8188 if( one_in( raw_dmg ) || one_in( 2 ) ) {
8189 return false;
8190 }
8191 } else {
8192 // Sturdy items and power armors never take chip damage.
8193 // Other armors have 0.5% of getting damaged from hits below their armor value.
8194 if( armor.has_flag( flag_STURDY ) || !one_in( 200 ) ) {
8195 return false;
8196 }
8197 }
8198
8199 const material_type &material = armor.get_random_material();
8200 std::string damage_verb = ( du.type == DT_BASH ) ? material.bash_dmg_verb() :
8201 material.cut_dmg_verb();
8202
8203 const std::string pre_damage_name = armor.tname();
8204 const std::string pre_damage_adj = armor.get_base_material().dmg_adj( armor.damage_level( 4 ) );
8205
8206 // add "further" if the damage adjective and verb are the same
8207 std::string format_string = ( pre_damage_adj == damage_verb ) ?
8208 _( "Your %1$s is %2$s further!" ) : _( "Your %1$s is %2$s!" );
8209 add_msg_if_player( m_bad, format_string, pre_damage_name, damage_verb );
8210 //item is damaged
8211 if( is_player() ) {
8212 SCT.add( point( posx(), posy() ), direction::NORTH, remove_color_tags( pre_damage_name ), m_neutral,
8213 damage_verb,
8214 m_info );
8215 }
8216
8217 return armor.mod_damage( armor.has_flag( "FRAGILE" ) ?
8219}
static const std::string flag_STURDY("STURDY")
size_t count() const
Definition: bodypart.h:268
const material_type & get_random_material() const
Get a material reference to a random material that this item is made of.
Definition: item.cpp:7171
bool mod_damage(int qty, damage_type dt)
Apply damage to const itemrained by min_damage and max_damage.
Definition: item.cpp:6251
int damage_level(int max) const
Scale item damage to the given number of levels.
Definition: item.cpp:704
int damage_resist(damage_type dt, bool to_self=false) const
Resistance provided by this item against damage type given by an enum.
Definition: item.cpp:6396
const material_type & get_base_material() const
Get the basic (main) material of this item.
Definition: item.cpp:7176
body_part_set get_covered_body_parts() const
Bitset of all covered body parts.
Definition: item.cpp:756
int get_coverage() const
Returns the relative coverage that this item has when worn.
Definition: item.cpp:5925
void mitigate_damage(damage_unit &du) const
Assuming that specified du hit the armor, reduce du based on the item's resistance to the damage type...
Definition: item.cpp:6388
std::string cut_dmg_verb() const
Definition: material.cpp:190
std::string dmg_adj(int damage) const
Definition: material.cpp:195
std::string bash_dmg_verb() const
Definition: material.cpp:185
float damage_multiplier
Definition: damage.h:40
static constexpr int damage_scale
Definition: itype.h:976

References _, scrollingcombattext::add(), Creature::add_msg_if_player(), damage_unit::amount, material_type::bash_dmg_verb(), body_part_set::count(), material_type::cut_dmg_verb(), item::damage_level(), damage_unit::damage_multiplier, item::damage_resist(), itype::damage_scale, material_type::dmg_adj(), DT_BASH, flag_STURDY(), item::get_base_material(), item::get_coverage(), item::get_covered_body_parts(), item::get_random_material(), item::has_flag(), Creature::is_player(), m_bad, m_info, m_neutral, item::mitigate_damage(), item::mod_damage(), NORTH, one_in(), posx(), posy(), remove_color_tags(), rng(), SCT, item::tname(), and damage_unit::type.

Referenced by absorb_hit().

◆ armwear_factor()

double Character::armwear_factor ( ) const

Same as footwear factor, but for arms.

Definition at line 8925 of file character.cpp.

8926{
8927 double ret = 0;
8928 if( wearing_something_on( bodypart_id( "arm_l" ) ) ) {
8929 ret += .5;
8930 }
8931 if( wearing_something_on( bodypart_id( "arm_r" ) ) ) {
8932 ret += .5;
8933 }
8934 return ret;
8935}
bool wearing_something_on(const bodypart_id &bp) const
Returns true if the character is wearing something on the entered body part.
Definition: character.cpp:8861

References cata::hash64_detail::ret, and wearing_something_on().

Referenced by suffer_in_sunlight().

◆ as_character() [1/2]

const Character * Character::as_character ( ) const
inlineoverridevirtual

Reimplemented from Creature.

Definition at line 235 of file character.h.

235 {
236 return this;
237 }

◆ as_character() [2/2]

Character * Character::as_character ( )
inlineoverridevirtual

Reimplemented from Creature.

Definition at line 232 of file character.h.

232 {
233 return this;
234 }

Referenced by debug_menu::character_edit_menu(), doors::close_door(), and emit_radio_signal().

◆ assign_activity() [1/2]

void Character::assign_activity ( const activity_id type,
int  moves = calendar::INDEFINITELY_LONG,
int  index = -1,
int  pos = INT_MIN,
const std::string &  name = "" 
)

Legacy activity assignment, does not work for any activites using the new activity_actor class and may cause issues with resuming.

TODO: delete this once migration of activites to the activity_actor system is complete

Definition at line 9191 of file character.cpp.

9193{
9195}
int moves
Definition: creature.h:582

References assign_activity(), Creature::moves, name, pos(), and type.

Referenced by activate_mutation(), activity_on_turn_move_loot(), assign_activity(), iuse::burrow(), game::butcher(), butcher_corpse_activity(), butcher_submenu(), cast_spell(), iuse::chop_logs(), chop_plank_activity(), iuse::chop_tree(), chop_tree_activity(), iuse::clear_rubble(), complete_construction(), construction_activity(), iuse::craft(), iuse::cut_log_into_planks(), iuse::dig(), iuse::dig_channel(), crafting::disassemble_all(), overmap_ui::display(), talk_function::do_butcher(), talk_function::do_chop_plank(), talk_function::do_chop_trees(), talk_function::do_construction(), talk_function::do_farming(), talk_function::do_fishing(), talk_function::do_mining(), npc::do_pulp(), player_activity::do_turn(), talk_function::do_vehicle_deconstruct(), talk_function::do_vehicle_repair(), drop(), game::exam_vehicle(), iuse::fill_pit(), npc::find_job_to_perform(), talk_function::find_mount(), aim_activity_actor::finish(), avatar_action::fire_ranged_bionic(), avatar_action::fire_ranged_mutation(), avatar_action::fire_wielded_weapon(), activity_handlers::fish_finish(), iuse::fishing_rod(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_handler(), talk_function::give_aid(), talk_function::give_all_aid(), avatar_funcs::gunmod_add(), iuse::hacksaw(), iuse::hairkit(), iuse::hammer(), iuse::hand_crank(), install_bionics(), vehicle::interact_with(), iuse::jackhammer(), loot(), iuse::makemound(), iuse::meditate(), monexamine::milk_source(), iuse::mind_splicer(), mine_activity(), iuse::oxytorch(), iuse::pickaxe(), game::place_player(), iexamine::plant_seed(), iuse::play_game(), monexamine::play_with(), avatar_action::plthrow(), iuse::portable_game(), prompt_disassemble_single(), avatar::read(), avatar_action::reload(), activity_handlers::resume_for_multi_activities(), iuse::robotcontrol(), iexamine::rubble(), iexamine::safe(), iuse::shavekit(), monexamine::shear_animal(), show_armor_layers_ui(), iexamine::shrub_wildveggies(), smash(), talk_function::sort_loot(), player::start_craft(), start_destination_activity(), game::start_hauling(), npc::start_read(), gates::toggle_gate(), avatar_funcs::toolmod_add(), iexamine::trap(), try_start_hacking(), avatar_funcs::try_to_sleep(), uninstall_bionic(), pick_lock_actor::use(), firestarter_actor::use(), enzlave_actor::use(), ammobelt_actor::use(), repair_item_actor::use(), heal_actor::use(), learn_spell_actor::use(), cast_spell_actor::use(), vehicle_activity(), iuse::vibe(), wait(), and wash_items().

◆ assign_activity() [2/2]

void Character::assign_activity ( const player_activity act,
bool  allow_resume = true 
)

Assigns activity to player, possibly resuming old activity if it's similar enough.

Definition at line 9197 of file character.cpp.

9198{
9199 bool resuming = false;
9200 if( allow_resume && !backlog.empty() && backlog.front().can_resume_with( act, *this ) ) {
9201 resuming = true;
9202 add_msg_if_player( _( "You resume your task." ) );
9203 activity = backlog.front();
9204 backlog.pop_front();
9205 } else {
9206 if( activity ) {
9207 backlog.push_front( activity );
9208 }
9209
9210 activity = act;
9211 }
9212
9213 activity.start_or_resume( *this, resuming );
9214
9215 if( is_npc() ) {
9217 npc *guy = dynamic_cast<npc *>( this );
9221 }
9222}
void cancel_stashed_activity()
Definition: character.cpp:902
std::list< player_activity > backlog
Definition: character.h:1579
Definition: npc.h:744
void set_attitude(npc_attitude new_attitude)
Definition: npc.cpp:3168
activity_id current_activity_id
Definition: npc.h:1212
void set_mission(npc_mission new_mission)
Definition: npc.cpp:3147
const activity_id & id() const
void start_or_resume(Character &who, bool resuming)
Preform necessary initialization to start or resume the activity.
@ NPCATT_ACTIVITY
Definition: npc.h:98
@ NPC_MISSION_ACTIVITY
Definition: npc.h:153
activity_id act
Definition: sounds.cpp:75

References _, act, activity, Creature::add_msg_if_player(), backlog, cancel_stashed_activity(), npc::current_activity_id, player_activity::id(), Creature::is_npc(), NPC_MISSION_ACTIVITY, NPCATT_ACTIVITY, npc::set_attitude(), npc::set_mission(), and player_activity::start_or_resume().

◆ assign_stashed_activity()

void Character::assign_stashed_activity ( )

Definition at line 924 of file character.cpp.

925{
929}
player_activity stashed_outbounds_backlog
Definition: character.h:1577
player_activity stashed_outbounds_activity
Definition: character.h:1576

References activity, backlog, cancel_stashed_activity(), stashed_outbounds_activity, and stashed_outbounds_backlog.

Referenced by npc::move().

◆ attack_cost()

int Character::attack_cost ( const item weap) const

Returns cost (in moves) of attacking with given item (no modifiers, like stuck)

Melee increases melee attack speed Dexterity increases attack speed

Definition at line 2279 of file melee.cpp.

2280{
2281 const int base_move_cost = weap.attack_cost() / 2;
2282 const int melee_skill = has_active_bionic( bionic_id( bio_cqb ) ) ? BIO_CQB_LEVEL : get_skill_level(
2283 skill_melee );
2284 /** @EFFECT_MELEE increases melee attack speed */
2285 const int skill_cost = static_cast<int>( ( base_move_cost * ( 15 - melee_skill ) / 15 ) );
2286 /** @EFFECT_DEX increases attack speed */
2287 const int dexbonus = dex_cur / 2;
2288 const int encumbrance_penalty = encumb( bp_torso ) +
2289 ( encumb( bp_hand_l ) + encumb( bp_hand_r ) ) / 2;
2290 const int ma_move_cost = mabuff_attack_cost_penalty();
2291 const float stamina_ratio = static_cast<float>( get_stamina() ) / static_cast<float>
2292 ( get_stamina_max() );
2293 // Increase cost multiplier linearly from 1.0 to 2.0 as stamina goes from 25% to 0%.
2294 const float stamina_penalty = 1.0 + std::max( ( 0.25f - stamina_ratio ) * 4.0f, 0.0f );
2295 const float ma_mult = mabuff_attack_cost_mult();
2296
2297 int move_cost = base_move_cost;
2298 // Stamina penalty only affects base/2 and encumbrance parts of the cost
2299 move_cost += encumbrance_penalty;
2300 move_cost *= stamina_penalty;
2301 move_cost += skill_cost;
2302 move_cost -= dexbonus;
2303
2305
2306 // Martial arts last. Flat has to be after mult, because comments say so.
2307 move_cost *= ma_mult;
2308 move_cost += ma_move_cost;
2309
2310 move_cost *= mutation_value( "attackcost_modifier" );
2311
2312 if( move_cost < 25 ) {
2313 return 25;
2314 }
2315
2316 return move_cost;
2317}
static int move_cost(const item &it, const tripoint &src, const tripoint &dest)
int get_stamina() const
Definition: character.cpp:7086
float mabuff_attack_cost_mult() const
Returns the multiplier on move cost of attacks.
float mutation_value(const std::string &val) const
Goes over all mutations, gets min and max of a value with given name.
Definition: character.cpp:6643
int mabuff_attack_cost_penalty() const
Returns the flat penalty to move cost of attacks.
int encumb(body_part bp) const
Returns ENC provided by armor, etc.
Definition: character.cpp:4025
double bonus_from_enchantments(double base, enchant_vals::mod value, bool round=false) const
Calculate bonus from enchantments for given base value.
Definition: character.cpp:7908
int get_stamina_max() const
Definition: character.cpp:7091
int attack_cost() const
Base number of moves (Creature::moves) that a single melee attack with this items takes.
Definition: item.cpp:5206
static constexpr int BIO_CQB_LEVEL
static const bionic_id bio_cqb("bio_cqb")
static const skill_id skill_melee("melee")

References item::attack_cost(), enchant_vals::ATTACK_COST, bio_cqb, BIO_CQB_LEVEL, bionic_id, bonus_from_enchantments(), bp_hand_l, bp_hand_r, bp_torso, dex_cur, encumb(), get_skill_level(), get_stamina(), get_stamina_max(), has_active_bionic(), mabuff_attack_cost_mult(), mabuff_attack_cost_penalty(), move_cost(), mutation_value(), and skill_melee.

Referenced by item::combat_info(), item::effective_dps(), melee_attack(), reach_attack(), and avatar_funcs::try_disarm_npc().

◆ attitude_to()

Creature::Attitude Character::attitude_to ( const Creature other) const
overridevirtual

Attitude (of this creature) towards another creature.

This might not be symmetric.

Implements Creature.

Reimplemented in npc.

Definition at line 10389 of file character.cpp.

10390{
10391 const auto m = dynamic_cast<const monster *>( &other );
10392 if( m != nullptr ) {
10393 if( m->friendly != 0 ) {
10394 return A_FRIENDLY;
10395 }
10396 switch( m->attitude( const_cast<Character *>( this ) ) ) {
10397 // player probably does not want to harm them, but doesn't care much at all.
10398 case MATT_FOLLOW:
10399 case MATT_FPASSIVE:
10400 case MATT_IGNORE:
10401 case MATT_FLEE:
10402 return A_NEUTRAL;
10403 // player does not want to harm those.
10404 case MATT_FRIEND:
10405 case MATT_ZLAVE:
10406 // Don't want to harm your zlave!
10407 return A_FRIENDLY;
10408 case MATT_ATTACK:
10409 return A_HOSTILE;
10410 case MATT_NULL:
10412 break;
10413 }
10414
10415 return A_NEUTRAL;
10416 }
10417
10418 const auto p = dynamic_cast<const npc *>( &other );
10419 if( p != nullptr ) {
10420 if( p->is_enemy() ) {
10421 return A_HOSTILE;
10422 } else if( p->is_player_ally() ) {
10423 return A_FRIENDLY;
10424 } else {
10425 return A_NEUTRAL;
10426 }
10427 } else if( &other == this ) {
10428 return A_FRIENDLY;
10429 }
10430
10431 return A_NEUTRAL;
10432}
@ A_NEUTRAL
Definition: creature.h:168
@ A_HOSTILE
Definition: creature.h:167
@ A_FRIENDLY
Definition: creature.h:169
@ MATT_ZLAVE
Definition: monster.h:63
@ MATT_FLEE
Definition: monster.h:59
@ NUM_MONSTER_ATTITUDES
Definition: monster.h:64
@ MATT_FRIEND
Definition: monster.h:57
@ MATT_FOLLOW
Definition: monster.h:61
@ MATT_ATTACK
Definition: monster.h:62
@ MATT_NULL
Definition: monster.h:56
@ MATT_IGNORE
Definition: monster.h:60
@ MATT_FPASSIVE
Definition: monster.h:58

References Creature::A_FRIENDLY, Creature::A_HOSTILE, Creature::A_NEUTRAL, MATT_ATTACK, MATT_FLEE, MATT_FOLLOW, MATT_FPASSIVE, MATT_FRIEND, MATT_IGNORE, MATT_NULL, MATT_ZLAVE, NUM_MONSTER_ATTITUDES, and other.

Referenced by game::is_hostile_within(), and show_armor_layers_ui().

◆ avoid_trap()

bool Character::avoid_trap ( const tripoint pos,
const trap tr 
) const
overridevirtual

Called when character triggers a trap, returns true if they don't set it off.

Dexterity increases chance to avoid traps Dodge increases chance to avoid traps

Implements Creature.

Definition at line 10265 of file character.cpp.

10266{
10267 /** @EFFECT_DEX increases chance to avoid traps */
10268
10269 /** @EFFECT_DODGE increases chance to avoid traps */
10270 int myroll = dice( 3, dex_cur + get_skill_level( skill_dodge ) * 1.5 );
10271 int traproll;
10272 if( tr.can_see( pos, *this ) ) {
10273 traproll = dice( 3, tr.get_avoidance() );
10274 } else {
10275 traproll = dice( 6, tr.get_avoidance() );
10276 }
10277
10278 return myroll >= traproll;
10279}
static const skill_id skill_dodge("dodge")
int dice(int number, int sides)
Definition: rng.cpp:85
int get_avoidance() const
Whether triggering the trap can be avoid (if greater than 0) and if so, this is compared to dodge ski...
Definition: trap.h:144
bool can_see(const tripoint &pos, const Character &p) const
Can player/npc p see this kind of trap, either by their memory (they known there is the trap) or by t...
Definition: trap.cpp:223

References trap::can_see(), dex_cur, dice(), trap::get_avoidance(), get_skill_level(), pos(), and skill_dodge.

◆ base_age()

int Character::base_age ( ) const

Definition at line 6778 of file character.cpp.

6779{
6780 return init_age;
6781}

References init_age.

Referenced by debug_menu::character_edit_menu(), char_creation::draw_age(), and set_description().

◆ base_height()

int Character::base_height ( ) const

Definition at line 6807 of file character.cpp.

6808{
6809 return init_height;
6810}
int init_height
height at character creation
Definition: character.h:2144

References init_height.

Referenced by debug_menu::character_edit_menu(), char_creation::draw_height(), and set_description().

◆ basic_symbol_color()

nc_color Character::basic_symbol_color ( ) const
overridevirtual

Implements Creature.

Reimplemented in npc.

Definition at line 6011 of file character.cpp.

6012{
6013 if( has_effect( effect_onfire ) ) {
6014 return c_red;
6015 }
6016 if( has_effect( effect_stunned ) ) {
6017 return c_light_blue;
6018 }
6019 if( has_effect( effect_boomered ) ) {
6020 return c_pink;
6021 }
6022 if( has_active_mutation( trait_id( "SHELL2" ) ) ) {
6023 return c_magenta;
6024 }
6025 if( is_underwater() ) {
6026 return c_blue;
6027 }
6030 return c_dark_gray;
6031 }
6032 if( move_mode == CMM_RUN ) {
6033 return c_yellow;
6034 }
6035 if( move_mode == CMM_CROUCH ) {
6036 return c_light_gray;
6037 }
6038 return c_white;
6039}
static const trait_id trait_DEBUG_CLOAK("DEBUG_CLOAK")
static const efftype_id effect_boomered("boomered")
static const bionic_id bio_cloak("bio_cloak")
static const efftype_id effect_stunned("stunned")
@ CMM_RUN
Definition: character.h:110
@ CMM_CROUCH
Definition: character.h:111
bool has_active_mutation(const trait_id &b) const
Definition: mutation.cpp:365
bool is_wearing_active_optcloak() const
Returns true if the player is wearing an active optical cloak.
Definition: character.cpp:3842
virtual bool is_underwater() const
Definition: creature.cpp:171
#define c_white
Definition: color.h:18
#define c_light_gray
Definition: color.h:19
#define c_blue
Definition: color.h:23
#define c_magenta
Definition: color.h:25
#define c_dark_gray
Definition: color.h:20
#define c_pink
Definition: color.h:31
#define c_light_blue
Definition: color.h:29
#define c_yellow
Definition: color.h:32
#define c_red
Definition: color.h:21
@ AEP_INVISIBLE
Definition: enums.h:110

References AEP_INVISIBLE, bio_cloak, c_blue, c_dark_gray, c_light_blue, c_light_gray, c_magenta, c_pink, c_red, c_white, c_yellow, CMM_CROUCH, CMM_RUN, effect_boomered, effect_onfire, effect_stunned, has_active_bionic(), has_active_mutation(), has_artifact_with(), Creature::has_effect(), has_trait(), Creature::is_underwater(), is_wearing_active_optcloak(), move_mode, trait_DEBUG_CLOAK, and trait_id.

Referenced by symbol_color().

◆ best_nearby_lifting_assist() [1/2]

int Character::best_nearby_lifting_assist ( ) const

Checks for items, tools, and vehicles with the Lifting quality near the character returning the highest quality in range.

Definition at line 2547 of file character.cpp.

2548{
2549 return best_nearby_lifting_assist( this->pos() );
2550}
int best_nearby_lifting_assist() const
Checks for items, tools, and vehicles with the Lifting quality near the character returning the highe...
Definition: character.cpp:2547

References best_nearby_lifting_assist(), and pos().

Referenced by best_nearby_lifting_assist(), veh_interact::cache_tool_availability_update_lifting(), can_do_activity_there(), and weight_carried_reduced_by().

◆ best_nearby_lifting_assist() [2/2]

int Character::best_nearby_lifting_assist ( const tripoint world_pos) const

Alternate version if you need to specify a different orign point for nearby vehicle sources of lifting used for operations on distant objects (e.g.

vehicle installation/uninstallation)

Definition at line 2552 of file character.cpp.

2553{
2554 const quality_id LIFT( "LIFT" );
2555 int mech_lift = 0;
2556 if( is_mounted() ) {
2557 auto mons = mounted_creature.get();
2558 if( mons->has_flag( MF_RIDEABLE_MECH ) ) {
2559 mech_lift = mons->mech_str_addition() + 10;
2560 }
2561 }
2562 return std::max( { this->max_quality( LIFT ), mech_lift,
2563 map_selector( this->pos(), PICKUP_RANGE, false ).max_quality( LIFT ),
2564 vehicle_selector( world_pos, PICKUP_RANGE, false ).max_quality( LIFT )
2565 } );
2566}
int PICKUP_RANGE
Items on the map with at most this distance to the player are considered available for crafting,...
shared_ptr_fast< monster > mounted_creature
Definition: character.h:1617
int max_quality(const quality_id &qual) const
Return maximum tool quality level provided by instance or INT_MIN if not found.
Definition: visitable.cpp:276
@ MF_RIDEABLE_MECH
Definition: mtype.h:115

References is_mounted(), visitable< T >::max_quality(), visitable< Character >::max_quality(), MF_RIDEABLE_MECH, mounted_creature, PICKUP_RANGE, and pos().

◆ best_quality_item()

item * Character::best_quality_item ( const quality_id qual)

get best quality item that this character has

Definition at line 4743 of file character.cpp.

4744{
4745 std::vector<item *> qual_inv = items_with( [qual]( const item & itm ) {
4746 return itm.has_quality( qual );
4747 } );
4748 item *best_qual = random_entry( qual_inv );
4749 for( const auto elem : qual_inv ) {
4750 if( elem->get_quality( qual ) > best_qual->get_quality( qual ) ) {
4751 best_qual = elem;
4752 }
4753 }
4754 return best_qual;
4755}
bool has_quality(const quality_id &qual, int level=1, int qty=1) const
Returns true if instance has amount (or more) items of at least quality level.
Definition: visitable.cpp:169
V random_entry(const C &container, D default_value)
Returns a random entry in the container.
Definition: rng.h:88

References visitable< T >::has_quality(), visitable< Character >::items_with(), and random_entry().

Referenced by chop_plank_activity(), chop_tree_activity(), generic_multi_activity_do(), and monexamine::shear_animal().

◆ best_shield()

item & Character::best_shield ( )

Returns the best item for blocking with.

Definition at line 1603 of file melee.cpp.

1604{
1605 // Note: wielded weapon, not one used for attacks
1606 int best_value = blocking_ability( primary_weapon() );
1607 // "BLOCK_WHILE_WORN" without a blocking tech need to be worn for the bonus
1608 best_value = best_value == 2 ? 0 : best_value;
1609 item *best = best_value > 0 ? &primary_weapon() : &null_item_reference();
1610 for( item &shield : worn ) {
1611 if( shield.has_flag( "BLOCK_WHILE_WORN" ) && blocking_ability( shield ) >= best_value ) {
1612 // in case a mod adds a shield that protects only one arm, the corresponding arm needs to be working
1613 if( shield.covers( bp_arm_l ) || shield.covers( bp_arm_r ) ) {
1614 if( shield.covers( bp_arm_l ) && !is_limb_disabled( bodypart_id( "arm_l" ) ) ) {
1615 best = &shield;
1616 } else if( shield.covers( bp_arm_r ) && !is_limb_disabled( bodypart_id( "arm_r" ) ) ) {
1617 best = &shield;
1618 }
1619 // leg guards
1620 } else if( ( shield.covers( bp_leg_l ) || shield.covers( bp_leg_r ) ) &&
1621 get_working_leg_count() >= 1 ) {
1622 best = &shield;
1623 // in case a mod adds an unusual worn blocking item, like a magic bracelet/crown, it's handled here
1624 } else {
1625 best = &shield;
1626 }
1627 }
1628 }
1629
1630 return *best;
1631}
int get_working_leg_count() const
Returns the number of functioning legs.
Definition: character.cpp:1245
bool is_limb_disabled(const bodypart_id &limb) const
Returns true if the limb is disabled(12.5% or less hp)
Definition: character.cpp:1257
item & null_item_reference()
Returns a reference to a null item (see item::is_null).
Definition: item.cpp:325
static int blocking_ability(const item &shield)
Definition: melee.cpp:1588

References blocking_ability(), bp_arm_l, bp_arm_r, bp_leg_l, bp_leg_r, get_working_leg_count(), is_limb_disabled(), null_item_reference(), primary_weapon(), and worn.

Referenced by block_hit(), and block_ranged_hit().

◆ bionic_armor_bonus()

float Character::bionic_armor_bonus ( const bodypart_id bp,
damage_type  dt 
) const

Check for passive bionics that provide armor, and returns the armor bonus This is called from player::passive_absorb_hit.

Definition at line 8221 of file character.cpp.

8222{
8223 float result = 0.0f;
8224 if( dt == DT_CUT || dt == DT_STAB ) {
8225 for( const bionic_id &bid : get_bionics() ) {
8226 const auto cut_prot = bid->cut_protec.find( bp.id() );
8227 if( cut_prot != bid->cut_protec.end() ) {
8228 result += cut_prot->second;
8229 }
8230 }
8231 } else if( dt == DT_BASH ) {
8232 for( const bionic_id &bid : get_bionics() ) {
8233 const auto bash_prot = bid->bash_protec.find( bp.id() );
8234 if( bash_prot != bid->bash_protec.end() ) {
8235 result += bash_prot->second;
8236 }
8237 }
8238 } else if( dt == DT_BULLET ) {
8239 for( const bionic_id &bid : get_bionics() ) {
8240 const auto bullet_prot = bid->bullet_protec.find( bp.id() );
8241 if( bullet_prot != bid->bullet_protec.end() ) {
8242 result += bullet_prot->second;
8243 }
8244 }
8245 }
8246
8247 return result;
8248}
std::vector< bionic_id > get_bionics() const
Definition: character.cpp:1794
const string_id< T > & id() const
Definition: ammo_effect.cpp:33

References bionic_data::bash_protec, bionic_data::bullet_protec, bionic_data::cut_protec, DT_BASH, DT_BULLET, DT_CUT, DT_STAB, get_bionics(), and int_id< T >::id().

Referenced by passive_absorb_hit().

◆ bionic_installation_issues()

std::map< bodypart_id, int > Character::bionic_installation_issues ( const bionic_id bioid) const

Definition at line 2578 of file bionics.cpp.

2579{
2580 std::map<bodypart_id, int> issues;
2581 if( !get_option < bool >( "CBM_SLOTS_ENABLED" ) ) {
2582 return issues;
2583 }
2584 for( const std::pair<const bodypart_str_id, int> &elem : bioid->occupied_bodyparts ) {
2585 const int lacked_slots = elem.second - get_free_bionics_slots( elem.first );
2586 if( lacked_slots > 0 ) {
2587 issues.emplace( elem.first, lacked_slots );
2588 }
2589 }
2590 return issues;
2591}
int get_free_bionics_slots(const bodypart_id &bp) const
Definition: bionics.cpp:2598
std::map< bodypart_str_id, int > occupied_bodyparts
Body part slots used to install this bionic, mapped to the amount of space required.
Definition: bionics.h:95

References get_free_bionics_slots(), and bionic_data::occupied_bodyparts.

Referenced by can_install_bionics(), and item::color_in_inventory().

◆ bionics_adjusted_skill()

float Character::bionics_adjusted_skill ( const skill_id most_important_skill,
const skill_id important_skill,
const skill_id least_important_skill,
int  skill_level = -1 
)

Calculate skill for (un)installing bionics.

Definition at line 1921 of file bionics.cpp.

1925{
1926 int pl_skill = bionics_pl_skill( most_important_skill, important_skill, least_important_skill,
1927 skill_level );
1928
1929 // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30
1930 float adjusted_skill = static_cast<float>( pl_skill ) - std::min( static_cast<float>( 40 ),
1931 static_cast<float>( pl_skill ) - static_cast<float>( pl_skill ) / static_cast<float>( 10.0 ) );
1932 adjusted_skill *= env_surgery_bonus( 1 ) + get_effect_int( effect_assisted );
1933 return adjusted_skill;
1934}
static const efftype_id effect_assisted("assisted")
float env_surgery_bonus(int radius)
Calculate skill bonus from tiles in radius.
Definition: bionics.cpp:2310
int bionics_pl_skill(const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
Calculate non adjusted skill for (un)installing bionics.
Definition: bionics.cpp:1936
int get_effect_int(const efftype_id &eff_id, body_part bp=num_bp) const
Returns the intensity of the matching effect.
Definition: creature.cpp:1290

References bionics_pl_skill(), effect_assisted, env_surgery_bonus(), and Creature::get_effect_int().

Referenced by best_installer(), can_install_bionics(), can_uninstall_bionic(), bionic_install_preset::get_failure_chance(), bionic_install_surgeon_preset::get_failure_chance(), bionic_uninstall_preset::get_failure_chance(), install_bionics(), game::save_cyborg(), and uninstall_bionic().

◆ bionics_install_failure()

void Character::bionics_install_failure ( const std::string &  installer,
int  difficulty,
int  success,
float  adjusted_skill 
)

Definition at line 2471 of file bionics.cpp.

2473{
2474 // "success" should be passed in as a negative integer representing how far off we
2475 // were for a successful install. We use this to determine consequences for failing.
2476 success = std::abs( success );
2477
2478 // failure level is decided by how far off the character was from a successful install, and
2479 // this is scaled up or down by the ratio of difficulty/skill. At high skill levels (or low
2480 // difficulties), only minor consequences occur. At low skill levels, severe consequences
2481 // are more likely.
2482 int failure_level = static_cast<int>( std::sqrt( success * 4.0 * difficulty / adjusted_skill ) );
2483 int fail_type = ( failure_level > 5 ? 5 : failure_level );
2484
2485 if( installer != "NOT_MED" ) {
2486 //~"Complications" is USian medical-speak for "unintended damage from a medical procedure".
2487 add_msg( m_neutral, _( "%s training helps to minimize the complications." ),
2488 installer );
2489 // In addition to the bonus, medical residents know enough OR protocol to avoid botching.
2490 // Take MD and be immune to faulty bionics.
2491 if( fail_type > 3 ) {
2492 fail_type = rng( 1, 3 );
2493 }
2494 }
2495
2496 switch( fail_type ) {
2497 case 0:
2498 case 1:
2500 break;
2501 case 2:
2502 case 3:
2503 do_damage_for_bionic_failure( 5, difficulty * 5 );
2504 break;
2505 case 4:
2506 case 5: {
2507 std::vector<bionic_id> valid;
2508 std::copy_if( begin( faulty_bionics ), end( faulty_bionics ), std::back_inserter( valid ),
2509 [&]( const bionic_id & id ) {
2510 return !has_bionic( id );
2511 } );
2512
2513 // We've got all the bad bionics!
2514 if( valid.empty() ) {
2515 if( has_max_power() ) {
2516 units::energy old_power = get_max_power_level();
2517 add_msg( m_bad, _( "%s lose power capacity!" ), disp_name() );
2522 }
2523 if( is_player() ) {
2524 g->memorial().add(
2525 pgettext( "memorial_male", "Lost %d units of power capacity." ),
2526 pgettext( "memorial_female", "Lost %d units of power capacity." ),
2527 units::to_kilojoule( old_power - get_max_power_level() ) );
2528 }
2529 // If no faults available and no power capacity, downgrade to second-worst complication.
2530 } else {
2531 do_damage_for_bionic_failure( 5, difficulty * 5 );
2532 break;
2533 }
2534 } else {
2535 const bionic_id &id = random_entry( valid );
2536 add_bionic( id );
2537 g->events().send<event_type::installs_faulty_cbm>( getID(), id );
2538 add_msg( m_bad,
2539 _( "Complication in installation caused a malfunction - %s. Uninstall it to clear the malfunction." ),
2540 id.obj().name );
2541 }
2542 }
2543 break;
2544 }
2545
2546}
bool has_max_power() const
Definition: character.cpp:1951
void set_max_power_level(const units::energy &npower_max)
Definition: character.cpp:1919
void do_damage_for_bionic_failure(int min_damage, int max_damage)
Definition: bionics.cpp:2431
@ installs_faulty_cbm
std::vector< bionic_id > faulty_bionics
Definition: bionics.cpp:217
const char * pgettext(const char *context, const char *msgid)

References _, add_bionic(), add_msg(), disp_name(), do_damage_for_bionic_failure(), anonymous_namespace{bionics.cpp}::faulty_bionics, units::from_kilojoule(), g, get_max_power_level(), getID(), has_bionic(), has_max_power(), id, installs_faulty_cbm, Creature::is_player(), m_bad, m_neutral, name, pgettext(), random_entry(), rng(), set_max_power_level(), behavior::success, and units::to_kilojoule().

Referenced by perform_install().

◆ bionics_pl_skill()

int Character::bionics_pl_skill ( const skill_id most_important_skill,
const skill_id important_skill,
const skill_id least_important_skill,
int  skill_level = -1 
)

Calculate non adjusted skill for (un)installing bionics.

Definition at line 1936 of file bionics.cpp.

1939{
1940 int pl_skill;
1941 if( skill_level == -1 ) {
1942 pl_skill = int_cur * 4 +
1943 get_skill_level( most_important_skill ) * 4 +
1944 get_skill_level( important_skill ) * 3 +
1945 get_skill_level( least_important_skill ) * 1;
1946 } else {
1947 // override chance as though all values were skill_level if it is provided
1948 pl_skill = 12 * skill_level;
1949 }
1950
1951 // Medical residents have some idea what they're doing
1952 if( has_trait( trait_PROF_MED ) ) {
1953 pl_skill += 3;
1954 }
1955
1956 // People trained in bionics gain an additional advantage towards using it
1957 if( has_trait( trait_PROF_AUTODOC ) ) {
1958 pl_skill += 7;
1959 }
1960 return pl_skill;
1961}
static const trait_id trait_PROF_MED("PROF_MED")
static const trait_id trait_PROF_AUTODOC("PROF_AUTODOC")

References get_skill_level(), has_trait(), int_cur, trait_PROF_AUTODOC, and trait_PROF_MED.

Referenced by bionics_adjusted_skill(), install_bionics(), and uninstall_bionic().

◆ bionics_uninstall_failure() [1/2]

void Character::bionics_uninstall_failure ( int  difficulty,
int  success,
float  adjusted_skill 
)

When a player fails the surgery.

Definition at line 1812 of file bionics.cpp.

1813{
1814 // "success" should be passed in as a negative integer representing how far off we
1815 // were for a successful removal. We use this to determine consequences for failing.
1816 success = std::abs( success );
1817
1818 // failure level is decided by how far off the character was from a successful removal, and
1819 // this is scaled up or down by the ratio of difficulty/skill. At high skill levels (or low
1820 // difficulties), only minor consequences occur. At low skill levels, severe consequences
1821 // are more likely.
1822 const int failure_level = static_cast<int>( std::sqrt( success * 4.0 * difficulty /
1823 adjusted_skill ) );
1824 const int fail_type = std::min( 5, failure_level );
1825
1826 if( fail_type <= 1 ) {
1827 add_msg( m_neutral, _( "The removal fails without incident." ) );
1828 return;
1829 }
1830
1831 add_msg( m_neutral, _( "The removal is a failure." ) );
1832 std::set<body_part> bp_hurt;
1833 switch( fail_type ) {
1834 case 2:
1835 case 3:
1837 break;
1838
1839 case 4:
1840 case 5:
1841 do_damage_for_bionic_failure( 5, difficulty * 5 );
1842 break;
1843 }
1844
1845}

References _, add_msg(), do_damage_for_bionic_failure(), m_neutral, and behavior::success.

Referenced by perform_uninstall(), and uninstall_bionic().

◆ bionics_uninstall_failure() [2/2]

void Character::bionics_uninstall_failure ( monster installer,
player patient,
int  difficulty,
int  success,
float  adjusted_skill 
)

When a monster fails the surgery.

Definition at line 1847 of file bionics.cpp.

1849{
1850
1851 // "success" should be passed in as a negative integer representing how far off we
1852 // were for a successful removal. We use this to determine consequences for failing.
1853 success = std::abs( success );
1854
1855 // failure level is decided by how far off the monster was from a successful removal, and
1856 // this is scaled up or down by the ratio of difficulty/skill. At high skill levels (or low
1857 // difficulties), only minor consequences occur. At low skill levels, severe consequences
1858 // are more likely.
1859 const int failure_level = static_cast<int>( std::sqrt( success * 4.0 * difficulty /
1860 adjusted_skill ) );
1861 const int fail_type = std::min( 5, failure_level );
1862
1863 bool u_see = sees( patient );
1864
1865 if( u_see || patient.is_player() ) {
1866 if( fail_type <= 1 ) {
1867 add_msg( m_neutral, _( "The removal fails without incident." ) );
1868 return;
1869 }
1870 switch( rng( 1, 5 ) ) {
1871 case 1:
1872 add_msg( m_mixed, _( "The %s flub the operation." ), installer.name() );
1873 break;
1874 case 2:
1875 add_msg( m_mixed, _( "The %s messes up the operation." ), installer.name() );
1876 break;
1877 case 3:
1878 add_msg( m_mixed, _( "The operation fails." ) );
1879 break;
1880 case 4:
1881 add_msg( m_mixed, _( "The operation is a failure." ) );
1882 break;
1883 case 5:
1884 add_msg( m_mixed, _( "The %s screws up the operation." ), installer.name() );
1885 break;
1886 }
1887 }
1888 switch( fail_type ) {
1889 case 2:
1890 case 3:
1891 do_damage_for_bionic_failure( failure_level, failure_level * 2 );
1892 break;
1893
1894 case 4:
1895 case 5:
1896 do_damage_for_bionic_failure( 5, difficulty * 5 );
1897 break;
1898 }
1899}
std::string name(unsigned int quantity=1) const
Definition: monster.cpp:489
bool is_player() const override
Definition: player.h:93

References _, add_msg(), do_damage_for_bionic_failure(), player::is_player(), m_mixed, m_neutral, monster::name(), rng(), sees(), and behavior::success.

◆ bionics_weight()

units::mass Character::bionics_weight ( ) const

Definition at line 6761 of file character.cpp.

6762{
6763 units::mass bio_weight = 0_gram;
6764 for( const bionic_id &bid : get_bionics() ) {
6765 if( !bid->included ) {
6766 bio_weight += bid->itype()->weight;
6767 }
6768 }
6769 return bio_weight;
6770}

References get_bionics().

Referenced by get_weight().

◆ block_hit()

bool Character::block_hit ( Creature source,
bodypart_id bp_hit,
damage_instance dam 
)
overridevirtual

Checks for valid block abilities and reduces damage accordingly.

Returns true if the player blocks

Strength increases attack blocking effectiveness with a limb or worn/wielded item Unarmed increases attack blocking effectiveness with a limb or worn/wielded item

Implements Creature.

Definition at line 1633 of file melee.cpp.

1634{
1635 // Shouldn't block if player is asleep
1637 return false;
1638 }
1639
1640 // fire martial arts on-getting-hit-triggered effects
1641 // these fire even if the attack is blocked (you still got hit)
1642 martial_arts_data->ma_ongethit_effects( *this );
1643
1644 if( blocks_left < 1 ) {
1645 return false;
1646 }
1647
1648 blocks_left--;
1649
1650 // This bonus absorbs damage from incoming attacks before they land,
1651 // but it still counts as a block even if it absorbs all the damage.
1652 float total_phys_block = mabuff_block_bonus();
1653
1654 // Extract this to make it easier to implement shields/multiwield later
1655 item &shield = best_shield();
1656 block_bonus = blocking_ability( shield );
1657 bool conductive_shield = shield.conductive();
1658 bool unarmed = primary_weapon().has_flag( "UNARMED_WEAPON" ) || primary_weapon().is_null();
1659 bool force_unarmed = martial_arts_data->is_force_unarmed();
1660
1661 int melee_skill = get_skill_level( skill_melee );
1662 int unarmed_skill = get_skill_level( skill_unarmed );
1663
1664 // Check if we are going to block with an item. This could
1665 // be worn equipment with the BLOCK_WHILE_WORN flag.
1666 const bool has_shield = !shield.is_null();
1667
1668 // boolean check if blocking is being done with unarmed or not
1669 const bool item_blocking = !force_unarmed && has_shield && !unarmed;
1670
1671 int block_score = 1;
1672
1673 /** @EFFECT_STR increases attack blocking effectiveness with a limb or worn/wielded item */
1674 /** @EFFECT_UNARMED increases attack blocking effectiveness with a limb or worn/wielded item */
1675 if( ( unarmed || force_unarmed ) ) {
1676 if( martial_arts_data->can_limb_block( *this ) ) {
1677 // block_bonus for limb blocks will be added when the limb is decided
1678 block_score = str_cur + melee_skill + unarmed_skill;
1679 } else if( has_shield ) {
1680 // We can still block with a worn item while unarmed. Use higher of melee and unarmed
1681 block_score = str_cur + block_bonus + std::max( melee_skill, unarmed_skill );
1682 }
1683 } else if( has_shield ) {
1684 block_score = str_cur + block_bonus + get_skill_level( skill_melee );
1685 } else {
1686 // Can't block with limbs or items (do not block)
1687 return false;
1688 }
1689
1690 // weapon blocks are preferred to limb blocks
1691 std::string thing_blocked_with;
1692 if( !force_unarmed && has_shield ) {
1693 thing_blocked_with = shield.tname();
1694 // TODO: Change this depending on damage blocked
1695 float wear_modifier = 1.0f;
1696 if( source != nullptr && source->is_hallucination() ) {
1697 wear_modifier = 0.0f;
1698 }
1699
1700 handle_melee_wear( shield, wear_modifier );
1701 } else {
1702 std::vector<bodypart_id> block_parts;
1703 if( martial_arts_data->can_leg_block( *this ) ) {
1704 block_parts.emplace_back( bodypart_id( "leg_l" ) );
1705 block_parts.emplace_back( bodypart_id( "leg_r" ) );
1706 }
1707 // If you have no martial arts you can still try to block with your arms.
1708 // But martial arts with leg blocks only don't magically get arm blocks.
1709 // Edge case: Leg block only martial arts gain arm blocks if both legs broken.
1710 if( martial_arts_data->can_arm_block( *this ) || block_parts.empty() ) {
1711 block_parts.emplace_back( bodypart_id( "arm_l" ) );
1712 block_parts.emplace_back( bodypart_id( "arm_r" ) );
1713 }
1714 block_parts.erase( std::remove_if( block_parts.begin(),
1715 block_parts.end(), [this]( bodypart_id & bpid ) {
1716 return get_part_hp_cur( bpid ) <= 0;
1717 } ), block_parts.end() );
1718
1719 const auto part_hp_cmp = [this]( const bodypart_id & lhs, const bodypart_id & rhs ) {
1720 return get_part_hp_cur( lhs ) < get_part_hp_cur( rhs );
1721 };
1722 auto healthiest = std::max_element( block_parts.begin(), block_parts.end(), part_hp_cmp );
1723 if( healthiest == block_parts.end() ) {
1724 // We have no parts with HP to block with.
1725 blocks_left = 0;
1726 return false;
1727 }
1728 bp_hit = *healthiest;
1729
1730 thing_blocked_with = body_part_name( bp_hit->token );
1731 }
1732
1733 if( has_shield ) {
1734 // Does our shield cover the limb we blocked with? If so, add the block bonus.
1735 block_score += shield.covers( bp_hit->token ) ? block_bonus : 0;
1736 }
1737
1738 // Map block_score to the logistic curve for a number between 1 and 0.
1739 // Basic beginner character (str 8, skill 0, basic weapon)
1740 // Will have a score around 10 and block about %15 of incoming damage.
1741 // More proficient melee character (str 10, skill 4, wbock_2 weapon)
1742 // will have a score of 20 and block about 45% of damage.
1743 // A highly expert character (str 14, skill 8 wblock_2)
1744 // will have a score in the high 20s and will block about 80% of damage.
1745 // As the block score approaches 40, damage making it through will dwindle
1746 // to nothing, at which point we're relying on attackers hitting enough to drain blocks.
1747 const float physical_block_multiplier = logarithmic_range( 0, 40, block_score );
1748
1749 float total_damage = 0.0;
1750 float damage_blocked = 0.0;
1751
1752 for( auto &elem : dam.damage_units ) {
1753 total_damage += elem.amount;
1754
1755 // block physical damage "normally"
1756 if( elem.type == DT_BASH || elem.type == DT_CUT || elem.type == DT_STAB ) {
1757 // use up our flat block bonus first
1758 float block_amount = std::min( total_phys_block, elem.amount );
1759 total_phys_block -= block_amount;
1760 elem.amount -= block_amount;
1761 damage_blocked += block_amount;
1762
1763 if( elem.amount <= std::numeric_limits<float>::epsilon() ) {
1764 continue;
1765 }
1766
1767 float previous_amount = elem.amount;
1768 elem.amount *= physical_block_multiplier;
1769 damage_blocked += previous_amount - elem.amount;
1770 }
1771
1772 // non-electrical "elemental" damage types do their full damage if unarmed,
1773 // but severely mitigated damage if not
1774 else if( elem.type == DT_HEAT || elem.type == DT_ACID || elem.type == DT_COLD ) {
1775 // Unarmed weapons won't block those
1776 if( item_blocking ) {
1777 float previous_amount = elem.amount;
1778 elem.amount /= 5;
1779 damage_blocked += previous_amount - elem.amount;
1780 }
1781 // electrical damage deals full damage if unarmed OR wielding a
1782 // conductive weapon
1783 } else if( elem.type == DT_ELECTRIC ) {
1784 // Unarmed weapons and conductive weapons won't block this
1785 if( item_blocking && !conductive_shield ) {
1786 float previous_amount = elem.amount;
1787 elem.amount /= 5;
1788 damage_blocked += previous_amount - elem.amount;
1789 }
1790 }
1791 }
1792
1793 std::string damage_blocked_description;
1794 // good/bad/ugly add_msg color code?
1795 // none, hardly any, a little, some, most, all
1796 float blocked_ratio = 0.0f;
1797 if( total_damage > std::numeric_limits<float>::epsilon() ) {
1798 blocked_ratio = ( total_damage - damage_blocked ) / total_damage;
1799 }
1800 if( blocked_ratio < std::numeric_limits<float>::epsilon() ) {
1801 //~ Damage amount in "You block <damage amount> with your <weapon>."
1802 damage_blocked_description = pgettext( "block amount", "all of the damage" );
1803 } else if( blocked_ratio < 0.2 ) {
1804 //~ Damage amount in "You block <damage amount> with your <weapon>."
1805 damage_blocked_description = pgettext( "block amount", "nearly all of the damage" );
1806 } else if( blocked_ratio < 0.4 ) {
1807 //~ Damage amount in "You block <damage amount> with your <weapon>."
1808 damage_blocked_description = pgettext( "block amount", "most of the damage" );
1809 } else if( blocked_ratio < 0.6 ) {
1810 //~ Damage amount in "You block <damage amount> with your <weapon>."
1811 damage_blocked_description = pgettext( "block amount", "a lot of the damage" );
1812 } else if( blocked_ratio < 0.8 ) {
1813 //~ Damage amount in "You block <damage amount> with your <weapon>."
1814 damage_blocked_description = pgettext( "block amount", "some of the damage" );
1815 } else if( blocked_ratio > std::numeric_limits<float>::epsilon() ) {
1816 //~ Damage amount in "You block <damage amount> with your <weapon>."
1817 damage_blocked_description = pgettext( "block amount", "a little of the damage" );
1818 } else {
1819 //~ Damage amount in "You block <damage amount> with your <weapon>."
1820 damage_blocked_description = pgettext( "block amount", "none of the damage" );
1821 }
1823 //~ %1$s is damage amount string (e.g. "most of the damage"), %2$s is weapon name
1824 _( "You block %1$s with your %2$s!" ),
1825 //~ %1$s is damage amount string (e.g. "most of the damage"), %2$s is weapon name
1826 _( "<npcname> blocks %1$s with their %2$s!" ),
1827 damage_blocked_description, thing_blocked_with );
1828
1829 // fire martial arts block-triggered effects
1830 martial_arts_data->ma_onblock_effects( *this );
1831
1832 // Check if we have any block counters
1833 matec_id tec = pick_technique( *source, shield, false, false, true );
1834
1835 if( tec != tec_none && !is_dead_state() ) {
1836 if( get_stamina() < get_stamina_max() / 3 ) {
1837 add_msg( m_bad, _( "You try to counterattack but you are too exhausted!" ) );
1838 } else if( primary_weapon().made_of( material_id( "glass" ) ) ) {
1839 add_msg( m_bad, _( "The item you are wielding is too fragile to counterattack with!" ) );
1840 } else {
1841 melee_attack( *source, false, &tec );
1842 }
1843 }
1844
1845 return true;
1846}
std::string body_part_name(body_part bp, int number)
Returns the matching name of the body_part token.
Definition: bodypart.cpp:319
double logarithmic_range(int min, int max, int pos)
Normalized logistic function.
int blocks_left
Definition: character.h:568
matec_id pick_technique(Creature &t, const item &weap, bool crit, bool dodge_counter, bool block_counter)
Returns a random valid technique.
Definition: melee.cpp:1174
int mabuff_block_bonus() const
Returns the block bonus from martial arts buffs.
bool in_sleep_state() const override
Definition: character.cpp:9322
void melee_attack(Creature &t, bool allow_special, const matec_id *force_technique=nullptr, bool allow_unarmed=true)
Sets up a melee attack and handles melee attack function calls.
Definition: melee.cpp:444
bool handle_melee_wear(item &shield, float wear_multiplier=1.0f)
Calculates melee weapon wear-and-tear through use, returns true if item is destroyed.
Definition: melee.cpp:216
item & best_shield()
Returns the best item for blocking with.
Definition: melee.cpp:1603
bool made_of(const material_id &m) const override
Definition: character.cpp:6245
virtual bool is_hallucination() const =0
virtual void add_msg_player_or_npc(const std::string &, const std::string &) const
Definition: creature.h:689
int block_bonus
Definition: creature.h:840
bool conductive() const
Whether the items is conductive.
Definition: item.cpp:6503
bool is_null() const
Definition: item.cpp:735
@ DT_COLD
Definition: damage.h:29
@ DT_ELECTRIC
Definition: damage.h:30
@ DT_ACID
Definition: damage.h:26
static const efftype_id effect_narcosis("narcosis")
static const matec_id tec_none("tec_none")
static const skill_id skill_unarmed("unarmed")

References _, add_msg(), Creature::add_msg_player_or_npc(), best_shield(), Creature::block_bonus, blocking_ability(), blocks_left, body_part_name(), item::conductive(), item::covers(), damage_instance::damage_units, DT_ACID, DT_BASH, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_STAB, effect_narcosis, Creature::get_part_hp_cur(), get_skill_level(), get_stamina(), get_stamina_max(), handle_melee_wear(), Creature::has_effect(), item::has_flag(), in_sleep_state(), is_dead_state(), Creature::is_hallucination(), item::is_null(), logarithmic_range(), m_bad, mabuff_block_bonus(), made_of(), martial_arts_data, melee_attack(), pgettext(), pick_technique(), primary_weapon(), skill_melee, skill_unarmed, str_cur, tec_none, and item::tname().

◆ block_ranged_hit()

bool Character::block_ranged_hit ( Creature source,
bodypart_id bp_hit,
damage_instance dam 
)
overridevirtual

Checks for chance that a ranged attack will hit other armor along the way.

Implements Creature.

Definition at line 10744 of file character.cpp.

10745{
10746 // Having access to more than one shield is not normal in vanilla, for now keep it simple and only give one chance to catch a bullet.
10747 item &shield = best_shield();
10748
10749 // Bail out early just in case, if blocking with bare hands.
10750 if( shield.is_null() ) {
10751 return false;
10752 }
10753
10754 const auto level = shield_level( shield );
10755 if( level == ShieldLevel::None || !is_covered_by_shield( bp_hit, shield ) ) {
10756 return false;
10757 }
10758 // Modify chance based on coverage and blocking ability, with lowered chance if hitting the legs. Exclude armguards here.
10759 const float technic_modifier = coverage_modifier_by_technic( level, is_leg_hit( bp_hit ) );
10760 const float shield_coverage_modifier = shield.get_coverage() * technic_modifier;
10761
10762 add_msg( m_debug, _( "block_ranged_hit success rate: %i%%" ),
10763 static_cast<int>( shield_coverage_modifier ) );
10764
10765 // Now roll coverage to determine if we intercept the shot.
10766 if( rng( 1, 100 ) > shield_coverage_modifier ) {
10767 add_msg( m_debug, _( "block_ranged_hit attempt failed" ) );
10768 return false;
10769 }
10770
10771 const float wear_modifier = is_valid_hallucination( source ) ? 0.0f : 1.0f;
10772 handle_melee_wear( shield, wear_modifier );
10773
10774 int total_damage = 0;
10775 int blocked_damage = 0;
10776 for( auto &elem : dam.damage_units ) {
10777 total_damage += elem.amount * elem.damage_multiplier;
10778 // Go through all relevant damage types and reduce by armor value if one exists.
10779 const float block_amount = get_block_amount( shield, elem );
10780 elem.amount -= block_amount;
10781 blocked_damage += block_amount;
10782 }
10783 blocked_damage = std::min( total_damage, blocked_damage );
10784 add_msg( m_debug, _( "expected base damage: %i" ), total_damage );
10785
10786 const std::string thing_blocked_with = shield.tname();
10787 if( blocked_damage > 0 ) {
10789 _( "The shot hits your %s, absorbing %i damage." ),
10790 _( "The shot hits <npcname>'s %s, absorbing %i damage." ),
10791 thing_blocked_with, blocked_damage );
10792 } else {
10794 _( "The shot hits your %s, but it punches right through!" ),
10795 _( "The shot hits <npcname>'s %s, but it punches right through!" ),
10796 thing_blocked_with );
10797 }
10798 return true;
10799}
auto coverage_modifier_by_technic(ShieldLevel level, bool leg_hit) -> float
auto is_valid_hallucination(Creature *source) -> bool
auto get_block_amount(const item &shield, const damage_unit &unit) -> int
auto is_leg_hit(const bodypart_id &bp_hit) -> bool
auto shield_level(const item &shield) -> ShieldLevel
auto is_covered_by_shield(const bodypart_id &bp_hit, const item &shield) -> bool
Check if the given shield can protect the given bodypart.

References _, add_msg(), Creature::add_msg_player_or_npc(), best_shield(), anonymous_namespace{character.cpp}::coverage_modifier_by_technic(), damage_instance::damage_units, anonymous_namespace{character.cpp}::get_block_amount(), item::get_coverage(), handle_melee_wear(), anonymous_namespace{character.cpp}::is_covered_by_shield(), anonymous_namespace{character.cpp}::is_leg_hit(), item::is_null(), anonymous_namespace{character.cpp}::is_valid_hallucination(), m_debug, rng(), anonymous_namespace{character.cpp}::shield_level(), and item::tname().

◆ blood_loss()

int Character::blood_loss ( const bodypart_id bp) const

Define blood loss (in percents)

Definition at line 5719 of file character.cpp.

5720{
5721 int hp_cur_sum = get_part_hp_cur( bp );
5722 int hp_max_sum = get_part_hp_max( bp );
5723
5724 if( bp == bodypart_id( "leg_l" ) || bp == bodypart_id( "leg_r" ) ) {
5725 hp_cur_sum = get_part_hp_cur( bodypart_id( "leg_l" ) ) + get_part_hp_cur( bodypart_id( "leg_r" ) );
5726 hp_max_sum = get_part_hp_max( bodypart_id( "leg_l" ) ) + get_part_hp_max( bodypart_id( "leg_r" ) );
5727 } else if( bp == bodypart_id( "arm_l" ) || bp == bodypart_id( "arm_r" ) ) {
5728 hp_cur_sum = get_part_hp_cur( bodypart_id( "arm_l" ) ) + get_part_hp_cur( bodypart_id( "arm_r" ) );
5729 hp_max_sum = get_part_hp_max( bodypart_id( "arm_l" ) ) + get_part_hp_max( bodypart_id( "arm_r" ) );
5730 }
5731
5732 hp_cur_sum = std::min( hp_max_sum, std::max( 0, hp_cur_sum ) );
5733 hp_max_sum = std::max( hp_max_sum, 1 );
5734 return 100 - ( 100 * hp_cur_sum ) / hp_max_sum;
5735}
int get_part_hp_max(const bodypart_id &id) const
Definition: creature.cpp:1611

References Creature::get_part_hp_cur(), and Creature::get_part_hp_max().

◆ bloodType()

field_type_id Character::bloodType ( ) const
overridevirtual

Implements Creature.

Definition at line 508 of file character.cpp.

509{
510 if( has_trait( trait_ACIDBLOOD ) ) {
511 return fd_acid;
512 }
514 return fd_blood_veggy;
515 }
517 return fd_blood_insect;
518 }
521 }
522 return fd_blood;
523}
static const trait_id trait_THRESH_CEPHALOPOD("THRESH_CEPHALOPOD")
static const trait_id trait_THRESH_PLANT("THRESH_PLANT")
static const trait_id trait_THRESH_INSECT("THRESH_INSECT")
static const trait_id trait_ACIDBLOOD("ACIDBLOOD")
static const trait_id trait_THRESH_SPIDER("THRESH_SPIDER")
field_type_id fd_blood_insect
Definition: field_type.cpp:363
field_type_id fd_blood_invertebrate
Definition: field_type.cpp:364
field_type_id fd_blood_veggy
Definition: field_type.cpp:362
field_type_id fd_blood
Definition: field_type.cpp:336
field_type_id fd_acid
Definition: field_type.cpp:342

References fd_acid, fd_blood, fd_blood_insect, fd_blood_invertebrate, fd_blood_veggy, has_trait(), trait_ACIDBLOOD, trait_THRESH_CEPHALOPOD, trait_THRESH_INSECT, trait_THRESH_PLANT, and trait_THRESH_SPIDER.

◆ blossoms()

void Character::blossoms ( )

Definition at line 8792 of file character.cpp.

8793{
8794 // Player blossoms are shorter-ranged, but you can fire much more frequently if you like.
8795 sounds::sound( pos(), 10, sounds::sound_t::combat, _( "Pouf!" ), false, "misc", "puff" );
8796 map &here = get_map();
8797 for( const tripoint &tmp : here.points_in_radius( pos(), 2 ) ) {
8798 here.add_field( tmp, fd_fungal_haze, rng( 1, 2 ) );
8799 }
8800}
field_type_id fd_fungal_haze
Definition: field_type.cpp:374

References _, map::add_field(), sounds::combat, fd_fungal_haze, get_map(), map::points_in_radius(), pos(), rng(), and sounds::sound().

Referenced by activate_mutation(), and suffer_while_awake().

◆ bmi()

float Character::bmi ( ) const

Definition at line 6751 of file character.cpp.

6752{
6753 return 25;
6754}

Referenced by bodyweight(), debug_menu::debug(), character_display::disp_info(), and suffer_mutation_power().

◆ bmr()

int Character::bmr ( ) const

Definition at line 6858 of file character.cpp.

6859{
6860 return metabolic_rate_base() * 2500;
6861}
float metabolic_rate_base() const
Stable base metabolic rate due to traits.

References metabolic_rate_base().

Referenced by debug_menu::debug(), fall_asleep(), get_hunger_description(), and update_stomach().

◆ body_window()

hp_part Character::body_window ( const std::string &  menu_header,
bool  show_all,
bool  precise,
int  normal_bonus,
int  head_bonus,
int  torso_bonus,
float  bleed,
float  bite,
float  infect,
float  bandage_power,
float  disinfectant_power 
) const

Displays menu with body part hp, optionally with hp estimation after healing.

Returns selected part. menu_header - name of item that triggers this menu show_all - show and enable choice of all limbs, not only healable precise - show numerical hp normal_bonus - heal normal limb head_bonus - heal head torso_bonus - heal torso bleed - chance to stop bleeding bite - chance to remove bite infect - chance to remove infection bandage_power - quality of bandage disinfectant_power - quality of disinfectant

Definition at line 5749 of file character.cpp.

5753{
5754 /* This struct establishes some kind of connection between the hp_part (which can be healed and
5755 * have HP) and the body_part. Note that there are more body_parts than hp_parts. For example:
5756 * Damage to bp_head, bp_eyes and bp_mouth is all applied on the HP of hp_head. */
5757 struct healable_bp {
5758 mutable bool allowed;
5759 bodypart_id bp;
5760 hp_part hp;
5761 std::string name; // Translated name as it appears in the menu.
5762 int bonus;
5763 };
5764 /* The array of the menu entries show to the player. The entries are displayed in this order,
5765 * it may be changed here. */
5766 std::array<healable_bp, num_hp_parts> parts = { {
5767 { false, bodypart_id( "head" ), hp_head, _( "Head" ), head_bonus },
5768 { false, bodypart_id( "torso" ), hp_torso, _( "Torso" ), torso_bonus },
5769 { false, bodypart_id( "arm_l" ), hp_arm_l, _( "Left Arm" ), normal_bonus },
5770 { false, bodypart_id( "arm_r" ), hp_arm_r, _( "Right Arm" ), normal_bonus },
5771 { false, bodypart_id( "leg_l" ), hp_leg_l, _( "Left Leg" ), normal_bonus },
5772 { false, bodypart_id( "leg_r" ), hp_leg_r, _( "Right Leg" ), normal_bonus },
5773 }
5774 };
5775
5776 int max_bp_name_len = 0;
5777 for( const auto &e : parts ) {
5778 max_bp_name_len = std::max( max_bp_name_len, utf8_width( e.name ) );
5779 }
5780
5781 uilist bmenu;
5782 bmenu.desc_enabled = true;
5783 bmenu.text = menu_header;
5784
5785 bmenu.hilight_disabled = true;
5786 bool is_valid_choice = false;
5787
5788 for( size_t i = 0; i < parts.size(); i++ ) {
5789 const auto &e = parts[i];
5790 const bodypart_id &bp = e.bp;
5791 const body_part bp_token = bp->token;
5792 const int maximal_hp = get_part_hp_max( bp );
5793 const int current_hp = get_part_hp_cur( bp );
5794 // This will c_light_gray if the part does not have any effects cured by the item/effect
5795 // (e.g. it cures only bites, but the part does not have a bite effect)
5796 const nc_color state_col = limb_color( bp, bleed > 0.0f, bite > 0.0f, infect > 0.0f );
5797 const bool has_curable_effect = state_col != c_light_gray;
5798 // The same as in the main UI sidebar. Independent of the capability of the healing item/effect!
5799 const nc_color all_state_col = limb_color( bp, true, true, true );
5800 // Broken means no HP can be restored, it requires surgical attention.
5801 const bool limb_is_broken = is_limb_broken( bp );
5802 const bool limb_is_mending = limb_is_broken &&
5804
5805 if( show_all ) {
5806 e.allowed = true;
5807 } else if( has_curable_effect ) {
5808 e.allowed = true;
5809 } else if( limb_is_broken ) {
5810 e.allowed = false;
5811 } else if( current_hp < maximal_hp && ( e.bonus != 0 || bandage_power > 0.0f ||
5812 disinfectant_power > 0.0f ) ) {
5813 e.allowed = true;
5814 } else {
5815 e.allowed = false;
5816 }
5817
5818 std::string msg;
5819 std::string desc;
5820 bool bleeding = has_effect( effect_bleed, bp_token );
5821 bool bitten = has_effect( effect_bite, bp_token );
5822 bool infected = has_effect( effect_infected, bp_token );
5823 bool bandaged = has_effect( effect_bandaged, bp_token );
5824 bool disinfected = has_effect( effect_disinfected, bp_token );
5825 const int b_power = get_effect_int( effect_bandaged, bp_token );
5826 const int d_power = get_effect_int( effect_disinfected, bp_token );
5827 int new_b_power = static_cast<int>( std::floor( bandage_power ) );
5828 if( bandaged ) {
5829 const effect &eff = get_effect( effect_bandaged, bp_token );
5830 if( new_b_power > eff.get_max_intensity() ) {
5831 new_b_power = eff.get_max_intensity();
5832 }
5833
5834 }
5835 int new_d_power = static_cast<int>( std::floor( disinfectant_power ) );
5836
5837 const auto &aligned_name = std::string( max_bp_name_len - utf8_width( e.name ), ' ' ) + e.name;
5838 std::string hp_str;
5839 if( limb_is_mending ) {
5840 desc += colorize( _( "It is broken but has been set and just needs time to heal." ),
5841 c_blue ) + "\n";
5842 const auto &eff = get_effect( effect_mending, bp_token );
5843 const int mend_perc = eff.is_null() ? 0.0 : 100 * eff.get_duration() / eff.get_max_duration();
5844
5845 if( precise ) {
5846 hp_str = colorize( string_format( "=%2d%%=", mend_perc ), c_blue );
5847 } else {
5848 const int num = mend_perc / 20;
5849 hp_str = colorize( std::string( num, '#' ) + std::string( 5 - num, '=' ), c_blue );
5850 }
5851 } else if( limb_is_broken ) {
5852 desc += colorize( _( "It is broken. It needs a splint or surgical attention." ), c_red ) + "\n";
5853 hp_str = "==%==";
5854 } else if( precise ) {
5855 hp_str = string_format( "%d", current_hp );
5856 } else {
5857 std::pair<std::string, nc_color> h_bar = get_hp_bar( current_hp, maximal_hp, false );
5858 hp_str = colorize( h_bar.first, h_bar.second ) +
5859 colorize( std::string( 5 - utf8_width( h_bar.first ), '.' ), c_white );
5860 }
5861 msg += colorize( aligned_name, all_state_col ) + " " + hp_str;
5862
5863 // BLEEDING block
5864 if( bleeding ) {
5865 desc += colorize( string_format( "%s: %s", get_effect( effect_bleed, bp_token ).get_speed_name(),
5866 get_effect( effect_bleed, bp_token ).disp_short_desc() ), c_red ) + "\n";
5867 if( bleed > 0.0f ) {
5868 desc += colorize( string_format( _( "Chance to stop: %d %%" ),
5869 static_cast<int>( bleed * 100 ) ), c_light_green ) + "\n";
5870 } else {
5871 desc += colorize( _( "This will not stop the bleeding." ),
5872 c_yellow ) + "\n";
5873 }
5874 }
5875 // BANDAGE block
5876 if( bandaged ) {
5877 desc += string_format( _( "Bandaged [%s]" ), texitify_healing_power( b_power ) ) + "\n";
5878 if( new_b_power > b_power ) {
5879 desc += colorize( string_format( _( "Expected quality improvement: %s" ),
5880 texitify_healing_power( new_b_power ) ), c_light_green ) + "\n";
5881 } else if( new_b_power > 0 ) {
5882 desc += colorize( _( "You don't expect any improvement from using this." ), c_yellow ) + "\n";
5883 }
5884 } else if( new_b_power > 0 && e.allowed ) {
5885 desc += colorize( string_format( _( "Expected bandage quality: %s" ),
5886 texitify_healing_power( new_b_power ) ), c_light_green ) + "\n";
5887 }
5888 // BITTEN block
5889 if( bitten ) {
5890 desc += colorize( string_format( "%s: ", get_effect( effect_bite,
5891 bp_token ).get_speed_name() ), c_red );
5892 desc += colorize( _( "It has a deep bite wound that needs cleaning." ), c_red ) + "\n";
5893 if( bite > 0 ) {
5894 desc += colorize( string_format( _( "Chance to clean and disinfect: %d %%" ),
5895 static_cast<int>( bite * 100 ) ), c_light_green ) + "\n";
5896 } else {
5897 desc += colorize( _( "This will not help in cleaning this wound." ), c_yellow ) + "\n";
5898 }
5899 }
5900 // INFECTED block
5901 if( infected ) {
5903 bp_token ).get_speed_name() ), c_red );
5904 desc += colorize( _( "It has a deep wound that looks infected. Antibiotics might be required." ),
5905 c_red ) + "\n";
5906 if( infect > 0 ) {
5907 desc += colorize( string_format( _( "Chance to heal infection: %d %%" ),
5908 static_cast<int>( infect * 100 ) ), c_light_green ) + "\n";
5909 } else {
5910 desc += colorize( _( "This will not help in healing infection." ), c_yellow ) + "\n";
5911 }
5912 }
5913 // DISINFECTANT (general) block
5914 if( disinfected ) {
5915 desc += string_format( _( "Disinfected [%s]" ),
5916 texitify_healing_power( d_power ) ) + "\n";
5917 if( new_d_power > d_power ) {
5918 desc += colorize( string_format( _( "Expected quality improvement: %s" ),
5919 texitify_healing_power( new_d_power ) ), c_light_green ) + "\n";
5920 } else if( new_d_power > 0 ) {
5921 desc += colorize( _( "You don't expect any improvement from using this." ),
5922 c_yellow ) + "\n";
5923 }
5924 } else if( new_d_power > 0 && e.allowed ) {
5925 desc += colorize( string_format(
5926 _( "Expected disinfection quality: %s" ),
5927 texitify_healing_power( new_d_power ) ), c_light_green ) + "\n";
5928 }
5929 // END of blocks
5930
5931 if( ( !e.allowed && !limb_is_broken ) || ( show_all && current_hp == maximal_hp &&
5932 !limb_is_broken && !bitten && !infected && !bleeding ) ) {
5933 desc += colorize( _( "Healthy." ), c_green ) + "\n";
5934 }
5935 if( !e.allowed ) {
5936 desc += colorize( _( "You don't expect any effect from using this." ), c_yellow );
5937 } else {
5938 is_valid_choice = true;
5939 }
5940 bmenu.addentry_desc( i, e.allowed, MENU_AUTOASSIGN, msg, desc );
5941 }
5942
5943 if( !is_valid_choice ) { // no body part can be chosen for this item/effect
5944 bmenu.init();
5945 bmenu.desc_enabled = false;
5946 bmenu.text = _( "No limb would benefit from it." );
5947 bmenu.addentry( parts.size(), true, 'q', "%s", _( "Cancel" ) );
5948 }
5949
5950 bmenu.query();
5951 if( bmenu.ret >= 0 && static_cast<size_t>( bmenu.ret ) < parts.size() &&
5952 parts[bmenu.ret].allowed ) {
5953 return parts[bmenu.ret].hp;
5954 } else {
5955 return num_hp_parts;
5956 }
5957}
int utf8_width(const char *s, const bool ignore_tags)
static const efftype_id effect_bleed("bleed")
static const efftype_id effect_infected("infected")
static const efftype_id effect_bite("bite")
static const trait_id trait_REGEN_LIZ("REGEN_LIZ")
static const std::string flag_SPLINT("SPLINT")
bool worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns true if the player is wearing an item with the given flag.
Definition: character.cpp:3264
nc_color limb_color(const bodypart_id &bp, bool bleed, bool bite, bool infect) const
Definition: character.cpp:5959
bool is_limb_broken(const bodypart_id &limb) const
Returns true if the limb is broken.
Definition: character.cpp:1264
virtual void bleed() const
Adds an appropriate blood splatter.
Definition: creature.cpp:127
int get_max_intensity() const
Returns the maximum intensity of an effect.
Definition: effect.cpp:853
time_duration get_duration() const
Returns the remaining duration of an effect.
Definition: effect.cpp:797
bool is_null() const
Returns true if the effect is the result of effect(), ie.
Definition: effect.cpp:553
int ret
Definition: ui.h:412
bool desc_enabled
Definition: ui.h:352
void addentry_desc(const std::string &str, const std::string &desc)
Definition: ui.cpp:952
bool hilight_disabled
Definition: ui.h:366
std::string text
Definition: ui.h:320
void addentry(const std::string &str)
Definition: ui.cpp:942
#define c_green
Definition: color.h:22
#define c_light_green
Definition: color.h:28
std::string texitify_healing_power(const int power)
Definition: effect.cpp:1478
void query(bool loop=true, int timeout=-1)
Handle input and update display.
Definition: ui.cpp:838
void init()
Sane defaults on initialization.
Definition: ui.cpp:152
std::pair< std::string, nc_color > get_hp_bar(const int cur_hp, const int max_hp, const bool is_mon)
Definition: output.cpp:1604
hp_part
Definition: pldata.h:32
@ hp_torso
Definition: pldata.h:34
@ hp_leg_r
Definition: pldata.h:38
@ hp_arm_r
Definition: pldata.h:36
@ hp_head
Definition: pldata.h:33
@ hp_arm_l
Definition: pldata.h:35
@ num_hp_parts
Definition: pldata.h:39
@ hp_leg_l
Definition: pldata.h:37
@ hp
Drains HP to recharge.
const int MENU_AUTOASSIGN
Definition: ui.h:31

References _, uilist::addentry(), uilist::addentry_desc(), Creature::bleed(), c_blue, c_green, c_light_gray, c_light_green, c_red, c_white, c_yellow, colorize(), uilist::desc_enabled, effect_bandaged, effect_bite, effect_bleed, effect_disinfected, effect_infected, effect_mending, flag_SPLINT(), Creature::get_effect(), Creature::get_effect_int(), get_hp_bar(), effect::get_max_intensity(), Creature::get_part_hp_cur(), Creature::get_part_hp_max(), Creature::has_effect(), has_trait(), uilist::hilight_disabled, hp, hp_arm_l, hp_arm_r, hp_head, hp_leg_l, hp_leg_r, hp_torso, uilist::init(), is_limb_broken(), limb_color(), MENU_AUTOASSIGN, name, num, num_hp_parts, uilist::query(), uilist::ret, string_format(), texitify_healing_power(), uilist::text, trait_REGEN_LIZ, utf8_width(), and worn_with_flag().

Referenced by game::npc_menu(), and pick_part_to_heal().

◆ bodypart_exposure()

std::map< bodypart_id, float > Character::bodypart_exposure ( )

Map body parts to their total exposure, from 0.0 (fully covered) to 1.0 (buck naked).

Clothing layers are multiplied, ex. two layers of 50% coverage will leave only 25% exposed. Used to determine suffering effects of albinism and solar sensitivity.

Definition at line 874 of file suffer.cpp.

875{
876 std::map<bodypart_id, float> bp_exposure;
877 // May need to iterate over all body parts several times, so make a copy
878 const std::vector<bodypart_id> all_body_parts = get_all_body_parts();
879
880 // Initially, all parts are assumed to be fully exposed
881 for( const bodypart_id &bp : all_body_parts ) {
882 bp_exposure[bp] = 1.0;
883 }
884 // For every item worn, for every body part, adjust coverage
885 for( const item &it : worn ) {
886 // What body parts does this item cover?
887 body_part_set covered = it.get_covered_body_parts();
888 for( const bodypart_id &bp : all_body_parts ) {
889 if( bp->token != num_bp && !covered.test( bp->token ) ) {
890 continue;
891 }
892 // How much exposure does this item leave on this part? (1.0 == naked)
893 float part_exposure = 1.0 - it.get_coverage() / 100.0f;
894 // Coverage multiplies, so two layers with 50% coverage will together give 75%
895 bp_exposure[bp] = bp_exposure[bp] * part_exposure;
896 }
897 }
898 return bp_exposure;
899}
@ num_bp
Definition: bodypart.h:53
std::vector< bodypart_id > get_all_body_parts(bool only_main=false) const
Returns body parts this creature have.
Definition: creature.cpp:1673
bool test(const body_part &bp) const
Definition: bodypart.h:250

References all_body_parts, Creature::get_all_body_parts(), num_bp, body_part_set::test(), and worn.

Referenced by suffer_from_sunburn().

◆ bodytemp_color()

nc_color Character::bodytemp_color ( int  bp) const

Define color for displaying the body temperature.

Definition at line 10462 of file character.cpp.

10463{
10464 nc_color color = c_light_gray; // default
10465 if( bp == bp_eyes ) {
10466 color = c_light_gray; // Eyes don't count towards warmth
10467 } else if( temp_conv[bp] > BODYTEMP_SCORCHING ) {
10468 color = c_red;
10469 } else if( temp_conv[bp] > BODYTEMP_VERY_HOT ) {
10471 } else if( temp_conv[bp] > BODYTEMP_HOT ) {
10472 color = c_yellow;
10473 } else if( temp_conv[bp] > BODYTEMP_COLD ) {
10474 color = c_green;
10475 } else if( temp_conv[bp] > BODYTEMP_VERY_COLD ) {
10477 } else if( temp_conv[bp] > BODYTEMP_FREEZING ) {
10478 color = c_cyan;
10479 } else if( temp_conv[bp] <= BODYTEMP_FREEZING ) {
10480 color = c_blue;
10481 }
10482 return color;
10483}
#define c_cyan
Definition: color.h:24
#define c_light_red
Definition: color.h:27
static nc_color color(const T_t &t)
static constexpr int BODYTEMP_SCORCHING
Definition: weather.h:42
static constexpr int BODYTEMP_VERY_HOT
Level 3 hotness.
Definition: weather.h:40
static constexpr int BODYTEMP_VERY_COLD
Frostbite timer will not improve while below this point.
Definition: weather.h:32
static constexpr int BODYTEMP_FREEZING
This value means frostbite occurs at the warmest temperature of 1C. If changed, the temp_conv calcula...
Definition: weather.h:30

References BODYTEMP_COLD, BODYTEMP_FREEZING, BODYTEMP_HOT, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, bp_eyes, c_blue, c_cyan, c_green, c_light_blue, c_light_gray, c_light_red, c_red, c_yellow, color(), and temp_conv.

Referenced by character_display::print_encumbrance().

◆ bodytemp_modifier_traits()

int Character::bodytemp_modifier_traits ( bool  overheated) const

Correction factor of the body temperature due to traits and mutations.

Definition at line 9546 of file character.cpp.

9547{
9548 int mod = 0;
9549 for( const trait_id &iter : get_mutations() ) {
9550 mod += overheated ? iter->bodytemp_min : iter->bodytemp_max;
9551 }
9552 return mod;
9553}
std::vector< trait_id > get_mutations(bool include_hidden=true) const
Get the idents of all traits/mutations.

References get_mutations().

Referenced by update_bodytemp().

◆ bodytemp_modifier_traits_floor()

int Character::bodytemp_modifier_traits_floor ( ) const

Correction factor of the body temperature due to traits and mutations for player lying on the floor.

Definition at line 9555 of file character.cpp.

9556{
9557 int mod = 0;
9558 for( const trait_id &iter : get_mutations() ) {
9559 mod += iter->bodytemp_sleep;
9560 }
9561 return mod;
9562}

References get_mutations().

Referenced by floor_warmth().

◆ bodyweight()

units::mass Character::bodyweight ( ) const

Definition at line 6756 of file character.cpp.

6757{
6758 return units::from_kilogram( bmi() * std::pow( height() / 100.0f, 2 ) );
6759}
int height() const
Definition: character.cpp:6837
float bmi() const
Definition: character.cpp:6751
constexpr quantity< value_type, mass_in_milligram_tag > from_kilogram(const value_type v)
Definition: units_mass.h:48

References bmi(), units::from_kilogram(), and height().

Referenced by get_weight(), and get_weight_string().

◆ bonus_damage()

float Character::bonus_damage ( bool  random) const

Returns the bonus bashing damage the player deals based on their stats.

Strength increases bashing damage

Definition at line 919 of file melee.cpp.

920{
921 /** @EFFECT_STR increases bashing damage */
922 if( random ) {
923 return rng_float( get_str() / 2.0f, get_str() );
924 }
925
926 return get_str() * 0.75f;
927}
virtual int get_str() const
Getters for stats exclusive to characters.
Definition: character.cpp:4088
type random()
Returns a random direction.
Definition: overmap.cpp:4220
double rng_float(double lo, double hi)
Definition: rng.cpp:28

References get_str(), om_direction::random(), and rng_float().

Referenced by draw_stats_info(), roll_bash_damage(), and set_stats().

◆ bonus_from_enchantments()

double Character::bonus_from_enchantments ( double  base,
enchant_vals::mod  value,
bool  round = false 
) const

Calculate bonus from enchantments for given base value.

Definition at line 7908 of file character.cpp.

7910{
7911 return enchantment_cache->calc_bonus( value, base, round );
7912}
pimpl< enchantment > enchantment_cache
Definition: character.h:2286

References enchantment_cache.

Referenced by armor_enchantment_adjust(), attack_cost(), calc_needs_rates(), get_stamina_max(), known_magic::mana_regen_rate(), known_magic::max_mana(), metabolic_rate_base(), run_cost(), and update_stamina().

◆ bp_to_hp()

hp_part Character::bp_to_hp ( body_part  bp)
static

Converts a body_part to an hp_part.

Definition at line 6454 of file character.cpp.

6455{
6456 switch( bp ) {
6457 case bp_head:
6458 case bp_eyes:
6459 case bp_mouth:
6460 return hp_head;
6461 case bp_torso:
6462 return hp_torso;
6463 case bp_arm_l:
6464 case bp_hand_l:
6465 return hp_arm_l;
6466 case bp_arm_r:
6467 case bp_hand_r:
6468 return hp_arm_r;
6469 case bp_leg_l:
6470 case bp_foot_l:
6471 return hp_leg_l;
6472 case bp_leg_r:
6473 case bp_foot_r:
6474 return hp_leg_r;
6475 default:
6476 return num_hp_parts;
6477 }
6478}

References bp_arm_l, bp_arm_r, bp_eyes, bp_foot_l, bp_foot_r, bp_hand_l, bp_hand_r, bp_head, bp_leg_l, bp_leg_r, bp_mouth, bp_torso, hp_arm_l, hp_arm_r, hp_head, hp_leg_l, hp_leg_r, hp_torso, and num_hp_parts.

Referenced by iexamine::autodoc(), explosion_handler::legacy_shrapnel(), explosion_handler::ExplosionProcess::project_shrapnel(), and heal_actor::use_healing_item().

◆ build_mut_dependency_map()

void Character::build_mut_dependency_map ( const trait_id mut,
std::unordered_map< trait_id, int > &  dependency_map,
int  distance 
)

Recursively traverses the mutation's prerequisites and replacements, building up a map.

Definition at line 7771 of file character.cpp.

7773{
7774 // Skip base traits and traits we've seen with a lower distance
7775 const auto lowest_distance = dependency_map.find( mut );
7776 if( !has_base_trait( mut ) && ( lowest_distance == dependency_map.end() ||
7777 distance < lowest_distance->second ) ) {
7778 dependency_map[mut] = distance;
7779 // Recurse over all prerequisite and replacement mutations
7780 const mutation_branch &mdata = mut.obj();
7781 for( const trait_id &i : mdata.prereqs ) {
7782 build_mut_dependency_map( i, dependency_map, distance + 1 );
7783 }
7784 for( const trait_id &i : mdata.prereqs2 ) {
7785 build_mut_dependency_map( i, dependency_map, distance + 1 );
7786 }
7787 for( const trait_id &i : mdata.replacements ) {
7788 build_mut_dependency_map( i, dependency_map, distance + 1 );
7789 }
7790 }
7791}
void build_mut_dependency_map(const trait_id &mut, std::unordered_map< trait_id, int > &dependency_map, int distance)
Recursively traverses the mutation's prerequisites and replacements, building up a map.
Definition: character.cpp:7771
bool has_base_trait(const trait_id &b) const
Returns true if the player has the entered starting trait.
Definition: mutation.cpp:119
const T & obj() const
Returns the actual object this id refers to.
Definition: achievement.cpp:63
std::vector< trait_id > replacements
Definition: mutation.h:263
std::vector< trait_id > prereqs
Definition: mutation.h:258
std::vector< trait_id > prereqs2
Definition: mutation.h:259

References build_mut_dependency_map(), has_base_trait(), string_id< T >::obj(), mutation_branch::prereqs, mutation_branch::prereqs2, mutation_branch::replacements, and second.

Referenced by build_mut_dependency_map(), and set_highest_cat_level().

◆ burn_fuel()

bool Character::burn_fuel ( bionic bio,
bool  start = false 
)

Convert fuel to bionic power.

Definition at line 1196 of file bionics.cpp.

1197{
1198 if( ( bio.info().fuel_opts.empty() && !bio.info().is_remote_fueled ) ||
1200 return true;
1201 }
1202 const bool is_metabolism_powered = bio.is_this_fuel_powered( fuel_type_metabolism );
1203 const bool is_cable_powered = bio.info().is_remote_fueled;
1204 std::vector<itype_id> fuel_available = get_fuel_available( bio.id );
1205 float effective_efficiency = get_effective_efficiency( bio, bio.info().fuel_efficiency );
1206
1207 if( is_cable_powered ) {
1208 const itype_id remote_fuel = find_remote_fuel();
1209 if( !remote_fuel.is_empty() ) {
1210 fuel_available.emplace_back( remote_fuel );
1211 if( remote_fuel == fuel_type_sun_light ) {
1212 const item *pack = item_worn_with_flag( "SOLARPACK_ON" );
1213 effective_efficiency = pack != nullptr ? pack->type->solar_efficiency : 0;
1214 }
1215 // TODO: check for available fuel in remote source
1216 } else if( !start ) {
1218 _( "Your %s runs out of fuel and turn off." ),
1219 _( "<npcname>'s %s runs out of fuel and turn off." ),
1220 bio.info().name );
1221 bio.powered = false;
1222 deactivate_bionic( bio, true );
1223 return false;
1224 }
1225 }
1226
1227 if( start && fuel_available.empty() ) {
1228 add_msg_player_or_npc( m_bad, _( "Your %s does not have enough fuel to start." ),
1229 _( "<npcname>'s %s does not have enough fuel to start." ),
1230 bio.info().name );
1231 deactivate_bionic( bio );
1232 return false;
1233 }
1234 // don't produce power on start to avoid instant recharge exploit by turning bionic ON/OFF
1235 //in the menu
1236 if( !start ) {
1237 for( const itype_id &fuel : fuel_available ) {
1238 const item &tmp_fuel = item( fuel );
1239 const int fuel_energy = tmp_fuel.fuel_energy();
1240 const bool is_perpetual_fuel = tmp_fuel.has_flag( flag_PERPETUAL );
1241
1242 int current_fuel_stock;
1243 if( is_metabolism_powered ) {
1244 current_fuel_stock = std::max( 0.0f, get_stored_kcal() - 0.8f *
1245 max_stored_kcal() );
1246 } else if( is_perpetual_fuel ) {
1247 current_fuel_stock = 1;
1248 } else if( is_cable_powered ) {
1249 current_fuel_stock = std::stoi( get_value( "rem_" + fuel.str() ) );
1250 } else {
1251 current_fuel_stock = std::stoi( get_value( fuel.str() ) );
1252 }
1253
1254 if( !bio.has_flag( flag_SAFE_FUEL_OFF ) &&
1255 get_power_level() + units::from_kilojoule( fuel_energy ) * effective_efficiency
1256 > get_max_power_level() ) {
1257 if( !bio.is_auto_start_keep_full() ) {
1258 if( is_metabolism_powered ) {
1259 add_msg_player_or_npc( m_info, _( "Your %s turns off to not waste calories." ),
1260 _( "<npcname>'s %s turns off to not waste calories." ),
1261 bio.info().name );
1262 } else if( is_perpetual_fuel ) {
1263 add_msg_player_or_npc( m_info, _( "Your %s turns off after filling your power banks." ),
1264 _( "<npcname>'s %s turns off after filling their power banks." ),
1265 bio.info().name );
1266 } else {
1267 add_msg_player_or_npc( m_info, _( "Your %s turns off to not waste fuel." ),
1268 _( "<npcname>'s %s turns off to not waste fuel." ),
1269 bio.info().name );
1270 }
1271 }
1272 bio.powered = false;
1273 deactivate_bionic( bio, true );
1274 return false;
1275 } else {
1276 if( current_fuel_stock > 0 ) {
1277 map &here = get_map();
1278 if( is_metabolism_powered ) {
1279 const int kcal_consumed = fuel_energy;
1280 // 1kcal = 4187 J
1281 const units::energy power_gain = kcal_consumed * 4184_J * effective_efficiency;
1282 mod_stored_kcal( -kcal_consumed );
1283 mod_power_level( power_gain );
1284 } else if( is_perpetual_fuel ) {
1285 if( fuel == fuel_type_sun_light ) {
1286 if( g->is_in_sunlight( pos() ) ) {
1287 const weather_type_id &wtype = current_weather( pos() );
1288 const float tick_sunlight = incident_sunlight( wtype, calendar::turn );
1289 const double intensity = tick_sunlight / default_daylight_level();
1290 mod_power_level( units::from_kilojoule( fuel_energy ) * intensity * effective_efficiency );
1291 }
1292 } else if( fuel == fuel_type_wind ) {
1293 int vehwindspeed = 0;
1294 const optional_vpart_position vp = here.veh_at( pos() );
1295 if( vp ) {
1296 // vehicle velocity in mph
1297 vehwindspeed = std::abs( vp->vehicle().velocity / 100 );
1298 }
1299 const weather_manager &wm = get_weather();
1300 const double windpower = get_local_windpower( wm.windspeed + vehwindspeed,
1302 g->is_sheltered( pos() ) );
1303 mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * effective_efficiency );
1304 } else {
1305 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_efficiency );
1306 }
1307 } else if( is_cable_powered ) {
1308 int to_consume = 1;
1310 to_consume = 0;
1311 }
1312 const int unconsumed = consume_remote_fuel( to_consume );
1313 if( unconsumed == 0 && to_consume == 1 ) {
1314 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_efficiency );
1315 current_fuel_stock -= 1;
1316 } else if( to_consume == 1 ) {
1317 current_fuel_stock = 0;
1318 }
1319 set_value( "rem_" + fuel.str(), std::to_string( current_fuel_stock ) );
1320 } else {
1321 current_fuel_stock -= 1;
1322 set_value( fuel.str(), std::to_string( current_fuel_stock ) );
1323 update_fuel_storage( fuel );
1324 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_efficiency );
1325 }
1326
1327 heat_emission( bio, fuel_energy );
1328 if( bio.info().power_gen_emission ) {
1329 here.emit_field( pos(), bio.info().power_gen_emission );
1330 }
1331 } else {
1332
1333 if( is_metabolism_powered ) {
1335 _( "Stored calories are below the safe threshold, your %s shuts down to preserve your health." ),
1336 _( "Stored calories are below the safe threshold, <npcname>'s %s shuts down to preserve their health." ),
1337 bio.info().name );
1338 } else {
1339 remove_value( fuel.str() );
1341 _( "Your %s runs out of fuel and turn off." ),
1342 _( "<npcname>'s %s runs out of fuel and turn off." ),
1343 bio.info().name );
1344 }
1345
1346 bio.powered = false;
1347 deactivate_bionic( bio, true );
1348 return false;
1349 }
1350 }
1351 }
1352 }
1353 return true;
1354}
static const std::string flag_SAFE_FUEL_OFF("SAFE_FUEL_OFF")
static const std::string flag_PERPETUAL("PERPETUAL")
static const itype_id fuel_type_wind("wind")
static const itype_id fuel_type_metabolism("metabolism")
static const itype_id fuel_type_muscle("muscle")
static const itype_id fuel_type_sun_light("sunlight")
double default_daylight_level()
How much light is provided in full daylight.
Definition: calendar.cpp:62
std::string to_string(const time_duration &d)
Returns a string showing a duration.
Definition: calendar.cpp:327
std::vector< itype_id > get_fuel_available(const bionic_id &bio) const
Return list of available fuel for this bionic.
Definition: character.cpp:2013
const item * item_worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns the first worn item with a given flag.
Definition: character.cpp:3272
virtual void mod_stored_kcal(int nkcal)
Modifiers for need values exclusive to characters.
Definition: character.cpp:4323
void heat_emission(bionic &bio, int fuel_energy)
Handle heat from exothermic power generation.
Definition: bionics.cpp:1497
float get_effective_efficiency(bionic &bio, float fuel_efficiency)
Applies modifier to fuel_efficiency and returns the resulting efficiency.
Definition: bionics.cpp:1517
int get_stored_kcal() const
Getter for need values exclusive to characters.
Definition: character.cpp:4318
int consume_remote_fuel(int amount)
Consume fuel used by remote powered bionic, return amount of request unfulfilled (0 if totally succes...
Definition: bionics.cpp:1454
void update_fuel_storage(const itype_id &fuel)
Updates which bionic contain fuel and which is empty.
Definition: character.cpp:2068
itype_id find_remote_fuel(bool look_only=false)
Find fuel used by remote powered bionic.
Definition: bionics.cpp:1400
void set_value(const std::string &key, const std::string &value)
Definition: creature.cpp:1371
float fuel_energy() const
Returns energy of one charge of this item as fuel for an engine.
Definition: item.cpp:6841
const itype * type
Definition: item.h:2160
void emit_field(const tripoint &pos, const emit_id &src, float mul=1.0f)
Runs one cycle of emission src which may result in propagation of fields.
Definition: map_field.cpp:1927
int winddirection
Definition: weather.h:194
const weather_type_id & current_weather(const tripoint &location, const time_point &t)
Definition: weather.cpp:143
int incident_sunlight(const weather_type_id &wtype, const time_point &t)
Amount of sunlight incident at the ground, taking weather and time of day into account.
Definition: weather.cpp:107
emit_id power_gen_emission
Type of field emitted by this bionic when it produces energy.
Definition: bionics.h:81
std::vector< itype_id > fuel_opts
Fuel types that can be used by this bionic.
Definition: bionics.h:67
float fuel_efficiency
Fraction of fuel energy converted to bionic power.
Definition: bionics.h:71
bool has_flag(const std::string &flag) const
Definition: bionics.cpp:2747
bool is_this_fuel_powered(const itype_id &this_fuel) const
Definition: bionics.cpp:2762
float solar_efficiency
Efficiency of solar energy conversion for solarpacks.
Definition: itype.h:1001

References _, Creature::add_msg_player_or_npc(), consume_remote_fuel(), current_weather(), deactivate_bionic(), default_daylight_level(), map::emit_field(), find_remote_fuel(), flag_PERPETUAL(), flag_SAFE_FUEL_OFF(), units::from_kilojoule(), bionic_data::fuel_efficiency, item::fuel_energy(), bionic_data::fuel_opts, fuel_type_metabolism, fuel_type_muscle, fuel_type_sun_light, fuel_type_wind, g, get_effective_efficiency(), get_fuel_available(), get_local_windpower(), get_map(), get_max_power_level(), get_power_level(), get_stored_kcal(), Creature::get_value(), get_weather(), global_omt_location(), bionic::has_flag(), item::has_flag(), heat_emission(), bionic::id, incident_sunlight(), bionic::info(), bionic::is_auto_start_keep_full(), string_id< T >::is_empty(), bionic_data::is_remote_fueled, bionic::is_this_fuel_powered(), item_worn_with_flag(), m_bad, m_info, max_stored_kcal(), mod_power_level(), mod_stored_kcal(), bionic_data::name, overmap_buffer, pos(), bionic_data::power_gen_emission, bionic::powered, Creature::remove_value(), Creature::set_value(), itype::solar_efficiency, overmapbuffer::ter(), to_string(), calendar::turn, item::type, update_fuel_storage(), map::veh_at(), weather_manager::winddirection, and weather_manager::windspeed.

Referenced by activate_bionic(), and process_bionic().

◆ burn_move_stamina()

void Character::burn_move_stamina ( int  moves)

Definition at line 7117 of file character.cpp.

7118{
7119 int overburden_percentage = 0;
7120 units::mass current_weight = weight_carried();
7121 // Make it at least 1 gram to avoid divide-by-zero warning
7122 units::mass max_weight = std::max( weight_capacity(), 1_gram );
7123 if( current_weight > max_weight ) {
7124 overburden_percentage = ( current_weight - max_weight ) * 100 / max_weight;
7125 }
7126
7127 int burn_ratio = get_option<int>( "PLAYER_BASE_STAMINA_BURN_RATE" );
7128 for( const bionic_id &bid : get_bionic_fueled_with( item( "muscle" ) ) ) {
7129 if( has_active_bionic( bid ) ) {
7130 burn_ratio = burn_ratio * 2 - 3;
7131 }
7132 }
7133 burn_ratio += overburden_percentage;
7134 if( move_mode == CMM_RUN ) {
7135 burn_ratio = burn_ratio * 7;
7136 }
7137 mod_stamina( -( ( moves * burn_ratio ) / 100.0 ) * stamina_move_cost_modifier() );
7138 add_msg( m_debug, "Stamina burn: %d", -( ( moves * burn_ratio ) / 100 ) );
7139 // Chance to suffer pain if overburden and stamina runs out or has trait BADBACK
7140 // Starts at 1 in 25, goes down by 5 for every 50% more carried
7141 if( ( current_weight > max_weight ) && ( has_trait( trait_BADBACK ) || get_stamina() == 0 ) &&
7142 one_in( 35 - 5 * current_weight / ( max_weight / 2 ) ) ) {
7143 add_msg_if_player( m_bad, _( "Your body strains under the weight!" ) );
7144 // 1 more pain for every 800 grams more (5 per extra STR needed)
7145 if( ( ( current_weight - max_weight ) / 800_gram > get_pain() && get_pain() < 100 ) ) {
7146 mod_pain( 1 );
7147 }
7148 }
7149}
static const trait_id trait_BADBACK("BADBACK")
std::vector< bionic_id > get_bionic_fueled_with(const item &it) const
Return bionic_id of bionics able to use it as fuel.
Definition: character.cpp:1865
units::mass weight_carried() const
Definition: character.cpp:2537
void mod_stamina(int mod)
Definition: character.cpp:7107
float stamina_move_cost_modifier() const
Definition: character.cpp:7151
virtual int get_pain() const
Definition: creature.cpp:1406

References _, add_msg(), Creature::add_msg_if_player(), CMM_RUN, get_bionic_fueled_with(), Creature::get_pain(), get_stamina(), has_active_bionic(), has_trait(), m_bad, m_debug, mod_pain(), mod_stamina(), move_mode, Creature::moves, one_in(), stamina_move_cost_modifier(), trait_BADBACK, weight_capacity(), and weight_carried().

Referenced by avatar_action::swim(), and game::walk_move().

◆ calc_all_parts_hp()

void Character::calc_all_parts_hp ( float  hp_mod = 0.0,
float  hp_adjust = 0.0,
int  str_max = 0 
)

Sets hp for all body parts.

Definition at line 1599 of file character.cpp.

1600{
1601 for( const std::pair<const bodypart_str_id, bodypart> &part : get_body() ) {
1602 bodypart &bp = get_part( part.first );
1603 int new_max = ( part.first->base_hp + str_max * 3 + hp_adjustment ) * hp_mod;
1604
1605 if( has_trait( trait_id( "GLASSJAW" ) ) && part.first == bodypart_str_id( "head" ) ) {
1606 new_max *= 0.8;
1607 }
1608
1609 float max_hp_ratio = static_cast<float>( new_max ) /
1610 static_cast<float>( bp.get_hp_max() );
1611
1612 int new_cur = std::ceil( static_cast<float>( bp.get_hp_cur() ) * max_hp_ratio );
1613
1614 bp.set_hp_max( std::max( new_max, 1 ) );
1615 bp.set_hp_cur( std::max( std::min( new_cur, new_max ), 0 ) );
1616 }
1617}
string_id< body_part_type > bodypart_str_id
Definition: bodypart.h:23
bodypart & get_part(const bodypart_id &id)
Definition: creature.cpp:1584
const std::map< bodypart_str_id, bodypart > & get_body() const
Definition: creature.cpp:1568
int get_hp_max() const
Definition: bodypart.cpp:402
int get_hp_cur() const
Definition: bodypart.cpp:397
void set_hp_max(int set)
Definition: bodypart.cpp:427
void set_hp_cur(int set)
Definition: bodypart.cpp:422

References Creature::get_body(), bodypart::get_hp_cur(), bodypart::get_hp_max(), Creature::get_part(), has_trait(), bodypart::set_hp_cur(), bodypart::set_hp_max(), str_max, and trait_id.

Referenced by recalc_hp().

◆ calc_encumbrance() [1/2]

char_encumbrance_data Character::calc_encumbrance ( ) const
protected

Recalculate encumbrance for all body parts.

Definition at line 3671 of file character.cpp.

3672{
3673 return calc_encumbrance( item() );
3674}
char_encumbrance_data calc_encumbrance() const
Recalculate encumbrance for all body parts.
Definition: character.cpp:3671

References calc_encumbrance().

Referenced by calc_encumbrance(), get_encumbrance(), on_item_takeoff(), on_item_wear(), and reset_encumbrance().

◆ calc_encumbrance() [2/2]

char_encumbrance_data Character::calc_encumbrance ( const item new_item) const
protected

Recalculate encumbrance for all body parts as if new_item was also worn.

Definition at line 3676 of file character.cpp.

3677{
3678
3680
3681 item_encumb( enc, new_item );
3682 mut_cbm_encumb( enc );
3683
3684 return enc;
3685}
void item_encumb(char_encumbrance_data &vals, const item &new_item) const
Applies encumbrance from items only If new_item is not null, then calculate under the asumption that ...
Definition: character.cpp:3982
void mut_cbm_encumb(char_encumbrance_data &vals) const
Applies encumbrance from mutations and bionics only.
Definition: character.cpp:4045

References item_encumb(), and mut_cbm_encumb().

◆ calc_needs_rates()

needs_rates Character::calc_needs_rates ( ) const

Definition at line 4918 of file character.cpp.

4919{
4920 const effect &sleep = get_effect( effect_sleep );
4921 const bool has_recycler = has_bionic( bio_recycler );
4922 const bool asleep = !sleep.is_null();
4923
4924 needs_rates rates;
4925 rates.hunger = metabolic_rate();
4926
4927 add_msg_if_player( m_debug, "Metabolic rate: %.2f", rates.hunger );
4928
4929 static const std::string player_thirst_rate( "PLAYER_THIRST_RATE" );
4930 rates.thirst = get_option< float >( player_thirst_rate );
4931 static const std::string thirst_modifier( "thirst_modifier" );
4932 rates.thirst *= 1.0f + mutation_value( thirst_modifier ) +
4934 static const std::string slows_thirst( "SLOWS_THIRST" );
4935 if( worn_with_flag( slows_thirst ) ) {
4936 rates.thirst *= 0.7f;
4937 }
4938
4939 static const std::string player_fatigue_rate( "PLAYER_FATIGUE_RATE" );
4940 rates.fatigue = get_option< float >( player_fatigue_rate );
4941 static const std::string fatigue_modifier( "fatigue_modifier" );
4942 rates.fatigue *= 1.0f + mutation_value( fatigue_modifier ) +
4944
4945 // Note: intentionally not in metabolic rate
4946 if( has_recycler ) {
4947 // Recycler won't help much with mutant metabolism - it is intended for human one
4948 rates.hunger = std::min( rates.hunger, std::max( 0.5f, rates.hunger - 0.5f ) );
4949 rates.thirst = std::min( rates.thirst, std::max( 0.5f, rates.thirst - 0.5f ) );
4950 }
4951
4952 if( asleep ) {
4953 static const std::string fatigue_regen_modifier( "fatigue_regen_modifier" );
4954 // Multiplied by 2 to account for legacy (bugged to always apply)
4955 // bonus for sleeping over 2 hours
4956 rates.recovery = 2.0f * ( 1.0f + mutation_value( fatigue_regen_modifier ) );
4957 if( is_hibernating() ) {
4958 // Hunger and thirst advance *much* more slowly whilst we hibernate.
4959 rates.hunger *= ( 1.0f / 7.0f );
4960 rates.thirst *= ( 1.0f / 7.0f );
4961 }
4962 rates.recovery -= static_cast<float>( get_perceived_pain() ) / 60;
4963
4964 } else {
4965 rates.recovery = 0;
4966 }
4967
4969 // Much of the body's needs are taken care of by the trees.
4970 // Hair Roots don't provide any bodily needs.
4972 rates.hunger *= 0.5f;
4973 rates.thirst *= 0.5f;
4974 rates.fatigue *= 0.5f;
4975 }
4976 }
4977
4979 // Transpiration, the act of moving nutrients with evaporating water, can take a very heavy toll on your thirst when it's really hot.
4980 rates.thirst *= ( ( get_weather().get_temperature( pos() ) - 32.5f ) / 40.0f );
4981 }
4982
4983 if( is_npc() ) {
4984 rates.hunger *= 0.25f;
4985 rates.thirst *= 0.25f;
4986 }
4987
4988 rates.thirst = std::max( rates.thirst, 0.0f );
4989 rates.hunger = std::max( rates.hunger, 0.0f );
4990 rates.fatigue = std::max( rates.fatigue, 0.0f );
4991 rates.recovery = std::max( rates.recovery, 0.0f );
4992
4993 return rates;
4994}
static const activity_id ACT_TREE_COMMUNION("ACT_TREE_COMMUNION")
static const trait_id trait_ROOTS2("ROOTS2")
static const bionic_id bio_recycler("bio_recycler")
static const efftype_id effect_sleep("sleep")
static const trait_id trait_TRANSPIRATION("TRANSPIRATION")
static const trait_id trait_ROOTS3("ROOTS3")
float metabolic_rate() const
Current metabolic rate due to traits, hunger, speed, etc.
bool is_hibernating() const
Returns if the player has hibernation mutation and is asleep and well fed.
Definition: character.cpp:5175
bool has_activity(const activity_id &type) const
Check if player currently has a given activity.
Definition: character.cpp:9224
int get_perceived_pain() const override
Returns perceived pain (reduced with painkillers)
Definition: character.cpp:803
int get_temperature(const tripoint &location) const
Definition: weather.cpp:1107
@ sleep
Will recharge only when character is asleep.
float hunger
Definition: character.h:203
float recovery
Definition: character.h:205
float fatigue
Definition: character.h:204
float thirst
Definition: character.h:202

References ACT_TREE_COMMUNION, Creature::add_msg_if_player(), bio_recycler, bonus_from_enchantments(), effect_sleep, needs_rates::fatigue, enchant_vals::FATIGUE, Creature::get_effect(), get_perceived_pain(), weather_manager::get_temperature(), get_weather(), has_activity(), has_bionic(), has_trait(), needs_rates::hunger, is_hibernating(), Creature::is_npc(), m_debug, metabolic_rate(), mutation_value(), pos(), needs_rates::recovery, sleep, needs_rates::thirst, enchant_vals::THIRST, trait_ROOTS2, trait_ROOTS3, trait_TRANSPIRATION, and worn_with_flag().

Referenced by update_needs(), and update_stomach().

◆ can_consume()

bool Character::can_consume ( const item it) const

Check character's capability of consumption overall.

Definition at line 1467 of file consumption.cpp.

1468{
1469 if( can_consume_as_is( it ) ) {
1470 return true;
1471 }
1472 // Checking NO_RELOAD to prevent consumption of `battery` when contained in `battery_car` (#20012)
1473 return !it.is_container_empty() && !it.has_flag( flag_NO_RELOAD ) &&
1475}
bool can_consume_as_is(const item &it) const
Check whether character can consume this very item.
item & front()
this is an artifact of the previous code using front() everywhere for contents.
bool is_container_empty() const
Whether this item has no contents at all.
Definition: item.cpp:6862
static const std::string flag_NO_RELOAD("NO_RELOAD")

References can_consume_as_is(), item::contents, flag_NO_RELOAD(), item_contents::front(), item::has_flag(), and item::is_container_empty().

Referenced by find_auto_consume(), and examine_item_menu::rate_action_eat().

◆ can_consume_as_is()

bool Character::can_consume_as_is ( const item it) const

Check whether character can consume this very item.

Definition at line 1457 of file consumption.cpp.

1458{
1459 return it.is_comestible() || can_consume_for_bionic( it );
1460}
bool can_consume_for_bionic(const item &it) const
bool is_comestible() const
Definition: item.cpp:6612

References can_consume_for_bionic(), and item::is_comestible().

Referenced by can_consume(), consume(), avatar_action::eat(), and get_consumable_from().

◆ can_consume_for_bionic()

bool Character::can_consume_for_bionic ( const item it) const

Definition at line 1462 of file consumption.cpp.

1463{
1465}
rechargeable_cbm get_cbm_rechargeable_with(const item &it) const

References get_cbm_rechargeable_with(), and none.

Referenced by can_consume_as_is().

◆ can_eat()

ret_val< edible_rating > Character::can_eat ( const item food) const

Can the food be [theoretically] eaten no matter the consequen ces?

Definition at line 642 of file consumption.cpp.

643{
644
645 const auto &comest = food.get_comestible();
646 if( !comest ) {
647 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible." ) );
648 }
649
650 if( food.has_flag( flag_INEDIBLE ) ) {
651 if( ( food.has_flag( flag_CATTLE ) && !has_trait( trait_THRESH_CATTLE ) ) ||
654 ( food.has_flag( flag_BIRD ) && !has_trait( trait_THRESH_BIRD ) ) ) {
655 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible to you." ) );
656 }
657 }
658
659 if( food.is_craft() ) {
660 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible in its current form." ) );
661 }
662
663 if( food.has_own_flag( "DIRTY" ) ) {
665 _( "This is full of dirt after being on the ground." ) );
666 }
667
668 const bool eat_verb = food.has_flag( flag_USE_EAT_VERB );
669 const bool edible = eat_verb || comest->comesttype == comesttype_FOOD;
670 const bool drinkable = !eat_verb && comest->comesttype == comesttype_DRINK;
671
672 // TODO: This condition occurs way too often. Unify it.
673 // update Sep. 26 2018: this apparently still occurs way too often. yay!
675 return ret_val<edible_rating>::make_failure( _( "You can't do that while underwater." ) );
676 }
677
678 if( edible || drinkable ) {
679 for( const auto &elem : food.type->materials ) {
680 if( !elem->edible() ) {
681 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible in its current form." ) );
682 }
683 }
684 }
685
686 if( !comest->tool.is_null() ) {
687 const bool has = item::count_by_charges( comest->tool )
688 ? has_charges( comest->tool, 1 )
689 : has_amount( comest->tool, 1 );
690 if( !has ) {
692 string_format( _( "You need a %s to consume that!" ),
693 item::nname( comest->tool ) ) );
694 }
695 }
696
697 // For all those folks who loved eating marloss berries. D:< mwuhahaha
699 !food.has_flag( flag_NO_INGEST ) ) {
701 _( "We can't eat that. It's not right for us." ) );
702 }
703 // Here's why PROBOSCIS is such a negative trait.
704 if( has_trait( trait_PROBOSCIS ) && !( drinkable || food.is_medication() ) ) {
706 _( "Ugh, you can't drink that!" ) );
707 }
708 if( has_trait( trait_CARNIVORE ) && ( compute_effective_nutrients( food ).kcal ) > 0 &&
711 _( "Eww. Inedible plant stuff!" ) );
712 }
713
716 // Like non-cannibal, but more strict!
718 _( "The thought of eating that makes you feel sick." ) );
719 }
720
721 for( const trait_id &mut : get_mutations() ) {
722 if( !food.made_of_any( mut.obj().can_only_eat ) && !mut.obj().can_only_eat.empty() &&
723 !food.has_flag( flag_NO_INGEST ) ) {
725 _( "You can't eat this." ) );
726 }
727 }
728
730}
nutrients compute_effective_nutrients(const item &) const
bool has_charges(const itype_id &it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >) const
Definition: character.cpp:9603
bool count_by_charges() const
Definition: item.cpp:6030
const cata::value_ptr< islot_comestible > & get_comestible() const
Definition: item.cpp:10153
static std::string nname(const itype_id &id, unsigned int quantity=1)
Returns the translated item name for the item with given id.
Definition: item.cpp:9951
bool is_craft() const
Definition: item.cpp:6948
bool made_of_any(const std::set< material_id > &mat_idents) const
Check we are made of at least one of a set (e.g.
Definition: item.cpp:6460
bool is_medication() const
Definition: item.cpp:6623
bool has_any_flag(const Container &flags) const
Definition: item.h:1407
bool has_own_flag(const std::string &flag) const
Checks whether item itself has given flag (doesn't check item type or gunmods).
Definition: item.cpp:5323
static ret_val make_success(T val=default_success::value)
Definition: ret_val.h:42
static ret_val make_failure(T val=default_failure::value)
Definition: ret_val.h:46
bool has_amount(const itype_id &what, int qty, bool pseudo=true, const std::function< bool(const item &)> &filter=return_true< item >) const
Check instance provides at least qty of an item (.
Definition: visitable.cpp:1111
static const trait_id trait_RUMINANT("RUMINANT")
const std::vector< std::string > carnivore_blacklist
static const std::string flag_INEDIBLE("INEDIBLE")
static const trait_id trait_HERBIVORE("HERBIVORE")
static const trait_id trait_CARNIVORE("CARNIVORE")
static const std::string comesttype_DRINK("DRINK")
static const trait_id trait_THRESH_BIRD("THRESH_BIRD")
const std::vector< std::string > herbivore_blacklist(temparray.begin(), temparray.end())
static const std::string flag_BIRD("BIRD")
static const trait_id trait_PROBOSCIS("PROBOSCIS")
static const std::string flag_USE_EAT_VERB("USE_EAT_VERB")
static const std::string flag_MYCUS_OK("MYCUS_OK")
static const std::string flag_CATTLE("CATTLE")
static const trait_id trait_THRESH_LUPINE("THRESH_LUPINE")
static const trait_id trait_THRESH_CATTLE("THRESH_CATTLE")
static const trait_id trait_THRESH_FELINE("THRESH_FELINE")
static const std::string comesttype_FOOD("FOOD")
static const std::string flag_CARNIVORE_OK("CARNIVORE_OK")
static const trait_id trait_WATERSLEEP("WATERSLEEP")
static const std::string flag_FELINE("FELINE")
static const trait_id trait_M_DEPENDENT("M_DEPENDENT")
static const std::string flag_NO_INGEST("NO_INGEST")
static const std::string flag_LUPINE("LUPINE")
std::vector< material_id > materials
Definition: itype.h:890

References _, carnivore_blacklist, comesttype_DRINK(), comesttype_FOOD(), compute_effective_nutrients(), item::count_by_charges(), edible, flag_BIRD(), flag_CARNIVORE_OK(), flag_CATTLE(), flag_FELINE(), flag_INEDIBLE(), flag_LUPINE(), flag_MYCUS_OK(), flag_NO_INGEST(), flag_USE_EAT_VERB(), item::get_comestible(), get_mutations(), visitable< Character >::has_amount(), item::has_any_flag(), has_charges(), item::has_flag(), item::has_own_flag(), has_trait(), herbivore_blacklist(), inedible_mutation, item::is_craft(), item::is_medication(), item::is_null(), Creature::is_underwater(), item::made_of_any(), ret_val< T >::make_failure(), ret_val< T >::make_success(), itype::materials, item::nname(), no_tool, string_format(), trait_CARNIVORE, trait_HERBIVORE, trait_M_DEPENDENT, trait_PROBOSCIS, trait_RUMINANT, trait_THRESH_BIRD, trait_THRESH_CATTLE, trait_THRESH_FELINE, trait_THRESH_LUPINE, trait_WATERSLEEP, and item::type.

Referenced by can_feed_furnace_with(), eat(), and will_eat().

◆ can_estimate_rot()

bool Character::can_estimate_rot ( ) const

True if the character has enough skill (in cooking or survival) to estimate time to rot.

Definition at line 1452 of file consumption.cpp.

1453{
1455}
static const skill_id skill_survival("survival")
static const skill_id skill_cooking("cooking")

References get_skill_level(), skill_cooking, and skill_survival.

Referenced by get_freshness_description().

◆ can_feed_furnace_with()

bool Character::can_feed_furnace_with ( const item it) const

Determine character's capability of recharging their CBMs.

Definition at line 1276 of file consumption.cpp.

1277{
1278 if( !it.flammable() || it.has_flag( flag_RADIOACTIVE ) || can_eat( it ).success() ) {
1279 return false;
1280 }
1281
1282 if( !has_active_bionic( bio_furnace ) ) {
1283 return false;
1284 }
1285
1286 // Not even one charge fits
1287 if( it.charges_per_volume( furnace_max_volume ) < 1 ) {
1288 return false;
1289 }
1290
1291 return !it.has_flag( flag_CORPSE );
1292}
ret_val< edible_rating > can_eat(const item &food) const
Can the food be [theoretically] eaten no matter the consequen ces?
bool flammable(int threshold=0) const
Whether the items is flammable.
Definition: item.cpp:8337
int charges_per_volume(const units::volume &vol) const
Number of (charges of) this item that fit into the given volume.
Definition: item.cpp:867
const units::volume furnace_max_volume(3_liter)
static const bionic_id bio_furnace("bio_furnace")
static const std::string flag_CORPSE("CORPSE")
static const std::string flag_RADIOACTIVE("RADIOACTIVE")

References bio_furnace, can_eat(), item::charges_per_volume(), flag_CORPSE(), flag_RADIOACTIVE(), item::flammable(), furnace_max_volume, has_active_bionic(), item::has_flag(), and behavior::success.

Referenced by feed_furnace_with(), and get_cbm_rechargeable_with().

◆ can_fuel_bionic_with()

bool Character::can_fuel_bionic_with ( const item it) const

Returns true if the character can fuel a bionic with the item.

Definition at line 1849 of file character.cpp.

1850{
1851 if( !it.is_fuel() ) {
1852 return false;
1853 }
1854
1855 for( const bionic_id &bid : get_bionics() ) {
1856 for( const itype_id &fuel : bid->fuel_opts ) {
1857 if( fuel == it.typeId() ) {
1858 return true;
1859 }
1860 }
1861 }
1862 return false;
1863}
const itype_id & typeId() const
return the unique identifier of the items underlying type
Definition: item.cpp:8374
bool is_fuel() const
Definition: item.cpp:6785

References get_bionics(), item::is_fuel(), and item::typeId().

Referenced by fuel_bionic_with(), and get_cbm_rechargeable_with().

◆ can_hear()

bool Character::can_hear ( const tripoint source,
int  volume 
) const

Definition at line 10281 of file character.cpp.

10282{
10283 if( is_deaf() ) {
10284 return false;
10285 }
10286
10287 // source is in-ear and at our square, we can hear it
10288 if( source == pos() && volume == 0 ) {
10289 return true;
10290 }
10291 const int dist = rl_dist( source, pos() );
10292 const float volume_multiplier = hearing_ability();
10293 return ( volume - get_weather().weather_id->sound_attn ) * volume_multiplier >= dist;
10294}
float hearing_ability() const
bool is_deaf() const
Definition: character.cpp:4510
quantity< int, volume_in_milliliter_tag > volume
Definition: units_volume.h:16

References get_weather(), hearing_ability(), is_deaf(), pos(), and rl_dist().

Referenced by game::chat(), iuse::geiger(), iuse::play_music(), iuse::talking_doll(), and musical_instrument_actor::use().

◆ can_install_bionics()

bool Character::can_install_bionics ( const itype type,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Is the installation possible.

Definition at line 2229 of file bionics.cpp.

2231{
2232 if( !type.bionic ) {
2233 debugmsg( "Tried to install NULL bionic" );
2234 return false;
2235 }
2236 if( is_mounted() ) {
2237 return false;
2238 }
2239
2240 const bionic_id &bioid = type.bionic->id;
2241 const int difficult = type.bionic->difficulty;
2242 float adjusted_skill;
2243
2244 if( autodoc ) {
2245 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
2248 skill_level );
2249 } else {
2250 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
2253 skill_level );
2254 }
2255 int chance_of_success = bionic_manip_cos( adjusted_skill, difficult );
2256
2257 std::vector<std::string> conflicting_muts;
2258 for( const trait_id &mid : bioid->canceled_mutations ) {
2259 if( has_trait( mid ) ) {
2260 conflicting_muts.push_back( mid->name() );
2261 }
2262 }
2263
2264 if( !conflicting_muts.empty() &&
2265 !query_yn(
2266 _( "Installing this bionic will remove the conflicting traits: %s. Continue anyway?" ),
2267 enumerate_as_string( conflicting_muts ) ) ) {
2268 return false;
2269 }
2270
2271 const std::map<bodypart_id, int> &issues = bionic_installation_issues( bioid );
2272 // show all requirements which are not satisfied
2273 if( !issues.empty() ) {
2274 std::string detailed_info;
2275 for( auto &elem : issues ) {
2276 //~ <Body part name>: <number of slots> more slot(s) needed.
2277 detailed_info += string_format( _( "\n%s: %i more slot(s) needed." ),
2278 body_part_name_as_heading( elem.first->token, 1 ),
2279 elem.second );
2280 }
2281 popup( _( "Not enough space for bionic installation!%s" ), detailed_info );
2282 return false;
2283 }
2284
2285 if( chance_of_success >= 100 ) {
2286 if( !g->u.query_yn(
2287 _( "Are you sure you wish to install the selected bionic?" ),
2288 100 - chance_of_success ) ) {
2289 return false;
2290 }
2291 } else {
2292 if( autodoc ) {
2293 if( !g->u.query_yn(
2294 _( "WARNING: There is a %i percent chance of complications, such as damage or faulty installation! Continue anyway?" ),
2295 ( 100 - chance_of_success ) ) ) {
2296 return false;
2297 }
2298 } else {
2299 if( !g->u.query_yn(
2300 _( "WARNING: There is a %i percent chance of complications, such as damage or faulty installation! The following skills affect self-installation: First Aid, Electronics, and Mechanics.\n\nContinue anyway?" ),
2301 ( 100 - chance_of_success ) ) ) {
2302 return false;
2303 }
2304 }
2305 }
2306
2307 return true;
2308}
int bionic_manip_cos(float adjusted_skill, int bionic_difficulty)
Definition: bionics.cpp:1964
static const skill_id skill_mechanics("mechanics")
static const skill_id skill_computer("computer")
static const skill_id skill_firstaid("firstaid")
static const skill_id skill_electronics("electronics")
std::string body_part_name_as_heading(body_part bp, int number)
Returns the name of the body parts in a context where the name is used as a heading or title e....
Definition: bodypart.cpp:343
std::map< bodypart_id, int > bionic_installation_issues(const bionic_id &bioid) const
Definition: bionics.cpp:2578
float bionics_adjusted_skill(const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
Calculate skill for (un)installing bionics.
Definition: bionics.cpp:1921
void autodoc(player &p, const tripoint &examp)
Definition: iexamine.cpp:4900
int popup(const std::string &text, PopupFlags flags)
Definition: output.cpp:764
std::string enumerate_as_string(const _Container &values, enumeration_conjunction conj=enumeration_conjunction::and_)
Definition: output.h:637
std::vector< trait_id > canceled_mutations
Mutations/trait that are removed upon installing this CBM.
Definition: bionics.h:110
std::string name() const

References _, iexamine::autodoc(), bionic_installation_issues(), bionic_manip_cos(), bionics_adjusted_skill(), body_part_name_as_heading(), bionic_data::canceled_mutations, debugmsg, enumerate_as_string(), g, has_trait(), is_mounted(), mutation_branch::name(), popup(), query_yn(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, string_format(), and type.

Referenced by iexamine::autodoc(), and install_bionic_actor::use().

◆ can_install_cbm_on_bp()

bool Character::can_install_cbm_on_bp ( const std::vector< bodypart_id > &  bps) const

Definition at line 454 of file mutation.cpp.

455{
456 bool can_install = true;
457 for( const trait_id &mut : get_mutations() ) {
458 for( const bodypart_id &bp : bps ) {
459 if( mut.obj().no_cbm_on_bp.count( bp.id() ) ) {
460 can_install = false;
461 break;
462 }
463 }
464 }
465 return can_install;
466}

References get_mutations().

Referenced by bionic_install_preset::get_denial().

◆ can_learn_by_disassembly()

bool Character::can_learn_by_disassembly ( const recipe rec) const

Definition at line 10609 of file character.cpp.

10610{
10611 return !rec.learn_by_disassembly.empty() &&
10613}
bool meets_skill_requirements(const std::map< skill_id, int > &req, const item &context=item()) const
Checks whether the character's skills meet the required.
Definition: character.cpp:3520
std::map< skill_id, int > learn_by_disassembly
Definition: recipe.h:113

References recipe::learn_by_disassembly, and meets_skill_requirements().

Referenced by crafting::complete_disassemble().

◆ can_miss_recovery()

bool Character::can_miss_recovery ( const item weap) const

Returns true if the player is able to use a miss recovery technique.

Definition at line 988 of file martialarts.cpp.

989{
990 if( !martial_arts_data->has_miss_recovery_tec( weap ) ) {
991 return false;
992 }
993
994 ma_technique tec = martial_arts_data->get_miss_recovery_tec( weap );
995
996 return tec.is_valid_character( *this );
997}
bool is_valid_character(const Character &u) const

References ma_technique::is_valid_character(), and martial_arts_data.

Referenced by melee_attack().

◆ can_mount()

bool Character::can_mount ( const monster critter) const

Definition at line 570 of file monexamine.cpp.

571{
572 const auto &avoid = get_path_avoid();
573 auto route = get_map().route( pos(), critter.pos(), get_pathfinding_settings(), avoid );
574
575 if( route.empty() ) {
576 return false;
577 }
578 return ( critter.has_flag( MF_PET_MOUNTABLE ) && critter.friendly == -1 &&
579 !critter.has_effect( effect_ai_waiting ) && !critter.has_effect( effect_ridden ) ) &&
580 ( ( critter.has_effect( effect_saddled ) && get_skill_level( skill_survival ) >= 1 ) ||
581 get_skill_level( skill_survival ) >= 4 ) && ( critter.get_size() >= ( get_size() + 1 ) &&
582 get_weight() <= critter.get_weight() * critter.get_mountable_weight_ratio() );
583}
units::mass get_weight() const override
Returns body weight plus weight of inventory and worn/wielded items.
Definition: character.cpp:3687
std::set< tripoint > get_path_avoid() const override
Returns a set of points we do not want to path through.
Definition: character.cpp:9956
m_size get_size() const override
Get size class of character.
Definition: character.cpp:575
const pathfinding_settings & get_pathfinding_settings() const override
Returns settings for pathfinding.
Definition: character.cpp:9970
std::vector< tripoint > route(const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
Calculate the best path using A*.
bool has_flag(m_flag f) const override
Definition: monster.cpp:894
m_size get_size() const override
Definition: monster.cpp:2729
const tripoint & pos() const override
Definition: monster.cpp:252
units::mass get_weight() const override
Definition: monster.cpp:2734
float get_mountable_weight_ratio() const
Definition: monster.cpp:2959
static const efftype_id effect_ai_waiting("ai_waiting")
static const efftype_id effect_ridden("ridden")
static const efftype_id effect_saddled("monster_saddled")
static const skill_id skill_survival("survival")
@ MF_PET_MOUNTABLE
Definition: mtype.h:164

References effect_ai_waiting, effect_ridden, effect_saddled, monster::friendly, get_map(), monster::get_mountable_weight_ratio(), get_path_avoid(), get_pathfinding_settings(), get_size(), monster::get_size(), get_skill_level(), get_weight(), monster::get_weight(), Creature::has_effect(), monster::has_flag(), MF_PET_MOUNTABLE, pos(), monster::pos(), map::route(), and skill_survival.

Referenced by talk_function::find_mount(), activity_handlers::find_mount_do_turn(), and monexamine::pet_menu().

◆ can_pick_volume() [1/2]

bool Character::can_pick_volume ( const item it) const

Definition at line 2706 of file character.cpp.

2707{
2708 inventory projected = inv;
2709 projected.add_item( it, true );
2710 return projected.volume() <= volume_capacity();
2711}
item & add_item(item newit, bool keep_invlet=false, bool assign_invlet=true, bool should_stack=true)
Definition: inventory.cpp:286
units::volume volume() const
Definition: inventory.cpp:1060

References inventory::add_item(), inv, inventory::volume(), and volume_capacity().

Referenced by avatar_funcs::add_or_drop_with_msg(), pickup_inventory_preset::get_denial(), give_item_to(), handle_harvest(), handle_problematic_pickup(), i_add_or_drop(), npc::mug_player(), pick_one_up(), conditional_t< T >::set_can_stow_weapon(), set_item_inventory(), and starting_inv().

◆ can_pick_volume() [2/2]

bool Character::can_pick_volume ( units::volume  volume) const

Definition at line 2713 of file character.cpp.

2714{
2715 // Might not be 100% true because some items restack to a very tiny bit less
2716 // but close enough not to matter
2717 return inv.volume() + volume <= volume_capacity();
2718}

References inv, inventory::volume(), and volume_capacity().

◆ can_pick_weight() [1/2]

bool Character::can_pick_weight ( const item it,
bool  safe = true 
) const

Definition at line 2720 of file character.cpp.

2721{
2722 return can_pick_weight( it.weight(), safe );
2723}
bool can_pick_weight(const item &it, bool safe=true) const
Definition: character.cpp:2720
units::mass weight(bool include_contents=true, bool integral=false) const
Definition: item.cpp:4983
void safe(player &p, const tripoint &examp)
Attempt to crack safe through audio-feedback manual lock manipulation.
Definition: iexamine.cpp:1420

References can_pick_weight(), iexamine::safe(), and item::weight().

Referenced by avatar_funcs::add_or_drop_with_msg(), can_pick_weight(), pickup_inventory_preset::get_denial(), give_item_to(), handle_harvest(), i_add_or_drop(), npc::mug_player(), pick_one_up(), and set_item_inventory().

◆ can_pick_weight() [2/2]

bool Character::can_pick_weight ( units::mass  weight,
bool  safe = true 
) const

Definition at line 2725 of file character.cpp.

2726{
2727 if( !safe ) {
2728 // Character can carry up to four times their maximum weight
2729 return ( weight_carried() + weight <= ( has_trait( trait_DEBUG_STORAGE ) ?
2730 units::mass_max : weight_capacity() * 4 ) );
2731 } else {
2732 return ( weight_carried() + weight <= weight_capacity() );
2733 }
2734}
static const trait_id trait_DEBUG_STORAGE("DEBUG_STORAGE")
constexpr mass mass_max
Definition: units_mass.h:28

References has_trait(), units::mass_max, iexamine::safe(), trait_DEBUG_STORAGE, weight_capacity(), and weight_carried().

◆ can_reload()

bool Character::can_reload ( const item it,
const itype_id ammo = itype_id() 
) const

Whether a tool or gun is potentially reloadable (optionally considering a specific ammo)

Parameters
itThing to be reloaded
ammoif set also check item currently compatible with this specific ammo or magazine
Note
items currently loaded with a detachable magazine are considered reloadable
items with integral magazines are reloadable if free capacity permits (+/- ammo matches)

Definition at line 11064 of file character.cpp.

11065{
11066 if( !it.is_reloadable_with( ammo ) ) {
11067 return false;
11068 }
11069
11070 if( it.is_ammo_belt() ) {
11071 const auto &linkage = it.type->magazine->linkage;
11072 if( linkage && !has_charges( *linkage, 1 ) ) {
11073 return false;
11074 }
11075 }
11076
11077 return true;
11078}
bool is_reloadable_with(const itype_id &ammo) const
Returns true if this item can be reloaded with specified ammo type at this moment.
Definition: item.cpp:6896
bool is_ammo_belt() const
Definition: item.cpp:6592
cata::value_ptr< islot_magazine > magazine
Definition: itype.h:829

References has_charges(), item::is_ammo_belt(), item::is_reloadable_with(), itype::magazine, and item::type.

Referenced by can_reload_item_or_mods(), npc::find_usable_ammo(), character_funcs::list_ammo(), examine_item_menu::rate_action_reload(), ammobelt_actor::use(), and wants_to_reload().

◆ can_run()

bool Character::can_run ( )

source of truth of whether a Character can run

Definition at line 1269 of file character.cpp.

1270{
1271 return ( get_stamina() > get_stamina_max() * 0.1f ) && get_working_leg_count() >= 2;
1272}

References get_stamina(), get_stamina_max(), and get_working_leg_count().

Referenced by game::on_move_effects(), and avatar::set_movement_mode().

◆ can_swap()

ret_val< bool > Character::can_swap ( const item it) const

Check player capable of swapping the side of a worn item.

Parameters
itThing to be swapped

Definition at line 3156 of file character.cpp.

3157{
3158 if( it.has_flag( flag_POWERARMOR_MOD ) ) {
3159 int max_layer = 2;
3160 std::vector< std::pair< body_part, int > > mod_parts;
3161 body_part bp = num_bp;
3162 bodypart_str_id bpid;
3163 for( std::size_t i = 0; i < static_cast< body_part >( num_bp ); ++i ) {
3164 bp = static_cast< body_part >( i );
3165 bpid = convert_bp( bp );
3166 if( it.get_covered_body_parts().test( bp ) && bpid->part_side != side::BOTH ) {
3167 mod_parts.emplace_back( bp, 0 );
3168 }
3169 }
3170 for( auto &elem : worn ) {
3171 for( std::pair< body_part, int > &mod_part : mod_parts ) {
3172 bpid = convert_bp( mod_part.first );
3173 if( elem.get_covered_body_parts().test( bpid->opposite_part->token ) &&
3174 elem.has_flag( flag_POWERARMOR_MOD ) ) {
3175 mod_part.second++;
3176 }
3177 }
3178 }
3179 for( std::pair< body_part, int > &mod_part : mod_parts ) {
3180 bpid = convert_bp( mod_part.first );
3181 if( mod_part.second >= max_layer ) {
3182 return ret_val<bool>::make_failure( _( "There is no space on the opposite side!" ) );
3183 }
3184 }
3185 }
3186
3188}
const bodypart_str_id & convert_bp(body_part bp)
Returns the new id for old token.
Definition: bodypart.cpp:185
static const std::string flag_POWERARMOR_MOD("POWERARMOR_MOD")
side part_side
Definition: bodypart.h:127
body_part token
Definition: bodypart.h:107
bodypart_str_id opposite_part
Definition: bodypart.h:125

References _, BOTH, convert_bp(), flag_POWERARMOR_MOD(), item::get_covered_body_parts(), item::has_flag(), ret_val< T >::make_failure(), ret_val< T >::make_success(), num_bp, body_part_type::opposite_part, body_part_type::part_side, body_part_set::test(), body_part_type::token, and worn.

Referenced by change_side().

◆ can_takeoff()

ret_val< bool > Character::can_takeoff ( const item it,
const std::list< item > *  res = nullptr 
) const

Check if character is capable of taking off given item.

Parameters
itItem to be taken off
resIf set, will expect to move item into the list.

Definition at line 3021 of file character.cpp.

3022{
3023 auto iter = std::find_if( worn.begin(), worn.end(), [ &it ]( const item & wit ) {
3024 return &it == &wit;
3025 } );
3026
3027 if( iter == worn.end() ) {
3028 return ret_val<bool>::make_failure( !is_npc() ? _( "You are not wearing that item." ) :
3029 _( "<npcname> is not wearing that item." ) );
3030 }
3031
3032 if( res == nullptr && !get_dependent_worn_items( it ).empty() ) {
3034 _( "You can't take off power armor while wearing other power armor components." ) :
3035 _( "<npcname> can't take off power armor while wearing other power armor components." ) );
3036 }
3037 if( it.has_flag( "NO_TAKEOFF" ) ) {
3039 _( "You can't take that item off." ) :
3040 _( "<npcname> can't take that item off." ) );
3041 }
3043}
std::list< item * > get_dependent_worn_items(const item &it) const
Returns all items that must be taken off before taking off this item.
Definition: character.cpp:2425

References _, get_dependent_worn_items(), item::has_flag(), Creature::is_npc(), ret_val< T >::make_failure(), ret_val< T >::make_success(), and worn.

Referenced by drop(), take_off_inventory_preset::get_denial(), avatar_action::plthrow(), examine_item_menu::rate_action_takeoff(), examine_item_menu::run(), takeoff(), and avatar_action::wield().

◆ can_uninstall_bionic()

bool Character::can_uninstall_bionic ( const bionic_id b_id,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Is The uninstallation possible.

Definition at line 1985 of file bionics.cpp.

1987{
1988 // If malfunctioning bionics doesn't have associated item it gets predefined difficulty
1989 int difficulty = BIONIC_NOITEM_DIFFICULTY;
1990 if( b_id->itype().is_valid() ) {
1991 const itype *type = &*b_id->itype();
1992 if( type->bionic ) {
1993 difficulty = type->bionic->difficulty;
1994 }
1995 }
1996
1997 if( !has_bionic( b_id ) ) {
1998 popup( _( "%s don't have this bionic installed." ), disp_name() );
1999 return false;
2000 }
2001
2002 if( ( b_id == bio_reactor ) || ( b_id == bio_advreactor ) ) {
2003 if( !g->u.query_yn(
2004 _( "WARNING: Removing a reactor may leave radioactive material! Remove anyway?" ) ) ) {
2005 return false;
2006 }
2007 }
2008
2009 for( const bionic_id &bid : get_bionics() ) {
2010 if( bid->is_included( b_id ) ) {
2011 popup( _( "%s must remove the %s bionic to remove the %s." ), installer.disp_name(),
2012 bid->name, b_id->name );
2013 return false;
2014 }
2015 }
2016
2017 if( b_id == bio_eye_optic ) {
2018 popup( _( "The Telescopic Lenses are part of %s eyes now. Removing them would leave %s blind." ),
2019 disp_name( true ), disp_name() );
2020 return false;
2021 }
2022
2023 // removal of bionics adds +2 difficulty over installation
2024 float adjusted_skill;
2025 if( autodoc ) {
2026 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
2029 skill_level );
2030 } else {
2031 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
2034 skill_level );
2035 }
2036 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty + 2 );
2037
2038 if( chance_of_success >= 100 ) {
2039 if( !g->u.query_yn(
2040 _( "Are you sure you wish to uninstall the selected bionic?" ),
2041 100 - chance_of_success ) ) {
2042 return false;
2043 }
2044 } else {
2045 if( !g->u.query_yn(
2046 _( "WARNING: %i percent chance of SEVERE damage to all body parts! Continue anyway?" ),
2047 ( 100 - static_cast<int>( chance_of_success ) ) ) ) {
2048 return false;
2049 }
2050 }
2051
2052 return true;
2053}
static const bionic_id bio_reactor("bio_reactor")
constexpr int BIONIC_NOITEM_DIFFICULTY
Definition: bionics.cpp:212
static const bionic_id bio_eye_optic("bio_eye_optic")
static const bionic_id bio_advreactor("bio_advreactor")
bool is_valid() const
Returns whether this id is valid, that means whether it refers to an existing object.
Definition: achievement.cpp:70
itype_id itype() const
Definition: bionics.cpp:250
Definition: itype.h:804

References _, iexamine::autodoc(), bio_advreactor, bio_eye_optic, bio_reactor, bionic_manip_cos(), BIONIC_NOITEM_DIFFICULTY, bionics_adjusted_skill(), disp_name(), g, get_bionics(), has_bionic(), string_id< T >::is_valid(), bionic_data::itype(), bionic_data::name, popup(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, and type.

Referenced by iexamine::autodoc().

◆ can_unwield()

ret_val< bool > Character::can_unwield ( const item it) const

Check whether character is capable of unwielding given item.

Definition at line 3125 of file character.cpp.

3126{
3127 if( it.has_flag( "NO_UNWIELD" ) ) {
3128 return ret_val<bool>::make_failure( _( "You cannot unwield your %s." ), it.tname() );
3129 }
3130
3132}

References _, item::has_flag(), ret_val< T >::make_failure(), ret_val< T >::make_success(), and item::tname().

Referenced by apply_damage(), drop(), inv_dump(), examine_item_menu::run(), unwield(), and avatar_action::wield().

◆ can_use()

bool Character::can_use ( const item it,
const item context = item() 
) const

Checks if character stats and skills meet minimum requirements for the item.

Prints an appropriate message if requirements not met.

Parameters
itItem we are checking
contextoptionally override effective item when checking contextual skills

Definition at line 2736 of file character.cpp.

2737{
2738 const auto &ctx = !context.is_null() ? context : it;
2739
2740 if( !meets_requirements( it, ctx ) ) {
2741 const std::string unmet( enumerate_unmet_requirements( it, ctx ) );
2742
2743 if( &it == &ctx ) {
2744 //~ %1$s - list of unmet requirements, %2$s - item name.
2745 add_msg_player_or_npc( m_bad, _( "You need at least %1$s to use this %2$s." ),
2746 _( "<npcname> needs at least %1$s to use this %2$s." ),
2747 unmet, it.tname() );
2748 } else {
2749 //~ %1$s - list of unmet requirements, %2$s - item name, %3$s - indirect item name.
2750 add_msg_player_or_npc( m_bad, _( "You need at least %1$s to use this %2$s with your %3$s." ),
2751 _( "<npcname> needs at least %1$s to use this %2$s with their %3$s." ),
2752 unmet, it.tname(), ctx.tname() );
2753 }
2754
2755 return false;
2756 }
2757
2758 return true;
2759}
std::string enumerate_unmet_requirements(const item &it, const item &context=item()) const
Returns a string of missed requirements (both stats and skills)
Definition: character.cpp:3369
bool meets_requirements(const item &it, const item &context=item()) const
Checks whether the character meets overall requirements to be able to use the item.
Definition: character.cpp:3542

References _, Creature::add_msg_player_or_npc(), enumerate_unmet_requirements(), item::is_null(), m_bad, meets_requirements(), and item::tname().

Referenced by npc_ai::best_mode_for_range(), can_use_heal_item(), avatar_funcs::gunmod_add(), ranged::gunmode_checks_common(), and avatar_funcs::toolmod_add().

◆ can_use_floor_warmth()

bool Character::can_use_floor_warmth ( ) const

Can the player lie down and cover self with blankets etc.

Definition at line 9442 of file character.cpp.

9443{
9444 static const auto allowed_activities = std::vector<activity_id> {
9445 activity_id( "ACT_WAIT" ),
9446 activity_id( "ACT_WAIT_NPC" ),
9447 activity_id( "ACT_WAIT_STAMINA" ),
9448 activity_id( "ACT_AUTODRIVE" ),
9449 activity_id( "ACT_READ" ),
9450 activity_id( "ACT_SOCIALIZE" ),
9451 activity_id( "ACT_MEDITATE" ),
9452 activity_id( "ACT_FISH" ),
9453 activity_id( "ACT_GAME" ),
9454 activity_id( "ACT_HAND_CRANK" ),
9455 activity_id( "ACT_HEATING" ),
9456 activity_id( "ACT_VIBE" ),
9457 activity_id( "ACT_TRY_SLEEP" ),
9458 activity_id( "ACT_OPERATION" ),
9459 activity_id( "ACT_TREE_COMMUNION" ),
9460 activity_id( "ACT_EAT_MENU" ),
9461 activity_id( "ACT_CONSUME_FOOD_MENU" ),
9462 activity_id( "ACT_CONSUME_DRINK_MENU" ),
9463 activity_id( "ACT_CONSUME_MEDS_MENU" ),
9464 activity_id( "ACT_STUDY_SPELL" ),
9465 };
9466
9467 return in_sleep_state() || has_activity( allowed_activities );
9468}
string_id< activity_type > activity_id
Definition: activity_type.h:15

References has_activity(), and in_sleep_state().

Referenced by update_bodytemp().

◆ can_use_grab_break_tec()

bool Character::can_use_grab_break_tec ( const item weap) const

Returns true if the player is able to use a grab breaking technique.

Definition at line 977 of file martialarts.cpp.

978{
979 if( !has_grab_break_tec() ) {
980 return false;
981 }
982
983 ma_technique tec = martial_arts_data->get_grab_break_tec( weap );
984
985 return tec.is_valid_character( *this );
986}
bool has_grab_break_tec() const override
Returns true if the player has a grab breaking technique available.

References has_grab_break_tec(), ma_technique::is_valid_character(), and martial_arts_data.

Referenced by mattack::grab().

◆ can_use_heal_item()

bool Character::can_use_heal_item ( const item med) const

Check for mutation disallowing the use of an healing item.

Definition at line 422 of file mutation.cpp.

423{
424 const itype_id heal_id = med.typeId();
425
426 bool can_use = false;
427 bool got_restriction = false;
428
429 for( const trait_id &mut : get_mutations() ) {
430 if( !mut.obj().can_only_heal_with.empty() ) {
431 got_restriction = true;
432 }
433 if( mut.obj().can_only_heal_with.count( heal_id ) ) {
434 can_use = true;
435 break;
436 }
437 }
438 if( !got_restriction ) {
439 can_use = !med.has_flag( "CANT_HEAL_EVERYONE" );
440 }
441
442 if( !can_use ) {
443 for( const trait_id &mut : get_mutations() ) {
444 if( mut.obj().can_heal_with.count( heal_id ) ) {
445 can_use = true;
446 break;
447 }
448 }
449 }
450
451 return can_use;
452}
bool can_use(const item &it, const item &context=item()) const
Checks if character stats and skills meet minimum requirements for the item.
Definition: character.cpp:2736

References can_use(), get_mutations(), item::has_flag(), and item::typeId().

Referenced by activatable_inventory_preset::get_denial(), and heal_actor::use_healing_item().

◆ can_wear()

ret_val< bool > Character::can_wear ( const item it,
bool  with_equip_change = false 
) const

Check character capable of wearing an item.

Parameters
itThing to be worn
with_equip_changeIf true returns if it could be worn if things were taken off

Definition at line 2761 of file character.cpp.

2762{
2763 if( !it.is_armor() ) {
2764 return ret_val<bool>::make_failure( _( "Putting on a %s would be tricky." ), it.tname() );
2765 }
2766
2767 if( has_trait( trait_WOOLALLERGY ) && ( it.made_of( material_id( "wool" ) ) ||
2768 it.has_own_flag( "wooled" ) ) ) {
2769 return ret_val<bool>::make_failure( _( "Can't wear that, it's made of wool!" ) );
2770 }
2771
2772 if( it.is_filthy() && has_trait( trait_SQUEAMISH ) ) {
2773 return ret_val<bool>::make_failure( _( "Can't wear that, it's filthy!" ) );
2774 }
2775
2776 if( !it.has_flag( flag_OVERSIZE ) && !it.has_flag( flag_SEMITANGIBLE ) ) {
2777 for( const trait_id &mut : get_mutations() ) {
2778 const auto &branch = mut.obj();
2779 if( branch.conflicts_with_item( it ) ) {
2781 _( "Your %s mutation prevents you from wearing your %s." ) :
2782 _( "My %s mutation prevents me from wearing this %s." ), branch.name(),
2783 it.type_name() );
2784 }
2785 }
2786 if( it.covers( bp_head ) && !it.has_flag( flag_SEMITANGIBLE ) &&
2787 !it.made_of( material_id( "wool" ) ) && !it.made_of( material_id( "cotton" ) ) &&
2788 !it.made_of( material_id( "nomex" ) ) && !it.made_of( material_id( "leather" ) ) &&
2790 has_trait( trait_ANTLERS ) ) ) {
2791 return ret_val<bool>::make_failure( _( "Cannot wear a helmet over %s." ),
2792 ( has_trait( trait_HORNS_POINTED ) ? _( "horns" ) :
2793 ( has_trait( trait_ANTENNAE ) ? _( "antennae" ) : _( "antlers" ) ) ) );
2794 }
2795 }
2796
2797 if( it.has_flag( flag_SPLINT ) ) {
2798 bool need_splint = false;
2799 for( const bodypart_id &bp : get_all_body_parts() ) {
2800 if( !it.covers( bp->token ) ) {
2801 continue;
2802 }
2803 if( is_limb_broken( bp ) && !worn_with_flag( flag_SPLINT, bp ) ) {
2804 need_splint = true;
2805 break;
2806 }
2807 }
2808 if( !need_splint ) {
2810 _( "You don't have any broken limbs this could help." )
2811 : _( "%s doesn't have any broken limbs this could help." ), name );
2812 }
2813 }
2814
2815 if( it.has_flag( flag_RESTRICT_HANDS ) && !has_two_arms() ) {
2816 return ret_val<bool>::make_failure( ( is_player() ? _( "You don't have enough arms to wear that." )
2817 : string_format( _( "%s doesn't have enough arms to wear that." ), name ) ) );
2818 }
2819
2820 //Everything checked after here should be something that could be solved by changing equipment
2821 if( with_equip_change ) {
2823 }
2824
2825 if( it.is_power_armor() ) {
2826 for( auto &elem : worn ) {
2827 if( ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() &&
2828 !elem.has_flag( flag_POWERARMOR_COMPATIBLE ) && !elem.is_power_armor() ) {
2829 return ret_val<bool>::make_failure( _( "Can't wear power armor over other gear!" ) );
2830 } else if( elem.has_flag( flag_POWERARMOR_EXO ) && it.has_flag( flag_POWERARMOR_EXO ) ) {
2831 return ret_val<bool>::make_failure( _( "Can't wear multiple exoskeletons!" ) );
2832 }
2833 }
2836 _( "You can only wear power armor components with power armor!" ) );
2837 }
2839 for( auto &elem : worn ) {
2840 if( elem.has_flag( flag_POWERARMOR_EXO ) &&
2841 ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() ) {
2842 return ret_val<bool>::make_failure( _( "Can't wear externals over an exoskeleton!" ) );
2843 } else if( elem.has_flag( flag_POWERARMOR_EXTERNAL ) &&
2844 ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() ) {
2845 return ret_val<bool>::make_failure( _( "Can't wear externals over one another!" ) );
2846 }
2847 }
2848 }
2849 if( it.has_flag( flag_POWERARMOR_MOD ) ) {
2850 int max_layer = 2;
2851 std::vector< std::pair< body_part, int > > mod_parts;
2852 std::vector< std::pair< body_part, bool > > attachments;
2853 body_part bp = num_bp;
2854 bodypart_str_id bpid;
2855 bool lhs = false;
2856 bool rhs = false;
2857 for( std::size_t i = 0; i < static_cast< body_part >( num_bp ); ++i ) {
2858 bp = static_cast< body_part >( i );
2859 if( it.get_covered_body_parts().test( bp ) ) {
2860 mod_parts.emplace_back( bp, 0 );
2861 attachments.emplace_back( bp, false );
2862 }
2863 }
2864 for( auto &elem : worn ) {
2865 // To check if there's an external/exoskeleton for the mod to attach to.
2866 for( std::pair< body_part, bool > &attachment : attachments ) {
2867 if( elem.get_covered_body_parts().test( attachment.first ) &&
2868 ( elem.has_flag( flag_POWERARMOR_EXO ) || elem.has_flag( flag_POWERARMOR_EXTERNAL ) ) ) {
2869 if( elem.is_sided() && elem.get_side() == bpid->part_side ) {
2870 attachment.second = true;
2871 } else {
2872 attachment.second = true;
2873 }
2874 }
2875 }
2876 // To check how many mods are on a given part.
2877 for( std::pair< body_part, int > &mod_part : mod_parts ) {
2878 bpid = convert_bp( mod_part.first );
2879 if( elem.get_covered_body_parts().test( mod_part.first ) &&
2880 elem.has_flag( flag_POWERARMOR_MOD ) ) {
2881 if( elem.is_sided() && elem.get_side() == bpid->part_side ) {
2882 mod_part.second++;
2883 } else {
2884 mod_part.second++;
2885 }
2886 }
2887 }
2888 }
2889 for( std::pair< body_part, bool > &attachment : attachments ) {
2890 if( !attachment.second ) {
2891 return ret_val<bool>::make_failure( _( "Nothing to attach the mod to!" ) );
2892 }
2893 }
2894 for( std::pair< body_part, int > &mod_part : mod_parts ) {
2895 bpid = convert_bp( mod_part.first );
2896 if( static_cast< body_part >( mod_part.first ) == bp_torso ) {
2897 max_layer = 3;
2898 }
2899 if( mod_part.second >= max_layer ) {
2900 if( !it.is_sided() || bpid->part_side == side::BOTH ) {
2901 return ret_val<bool>::make_failure( _( "Can't wear any more mods on that body part!" ) );
2902 } else {
2903 if( bpid->part_side == side::LEFT ) {
2904 lhs = true;
2905 } else {
2906 rhs = true;
2907 }
2908 if( lhs && rhs ) {
2909 return ret_val<bool>::make_failure( _( "No more space for that mod!" ) );
2910 }
2911 }
2912 }
2913 }
2914 }
2915 } else {
2916 // Only headgear can be worn with power armor, except other power armor components.
2917 // You can't wear headgear if power armor helmet is already sitting on your head.
2918 for( auto &elem : worn ) {
2920 ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() ) ) {
2921 return ret_val<bool>::make_failure( _( "Can't wear %s with power armor!" ), it.tname() );
2922 }
2923 }
2924 }
2925
2926 // Check if we don't have both hands available before wearing a briefcase, shield, etc. Also occurs if we're already wearing one.
2927 const item &weapon = primary_weapon();
2929 weapon.is_two_handed( *this ) ) ) {
2930 return ret_val<bool>::make_failure( ( is_player() ? _( "You don't have a hand free to wear that." )
2931 : string_format( _( "%s doesn't have a hand free to wear that." ), name ) ) );
2932 }
2933
2934 for( auto &i : worn ) {
2935 if( i.has_flag( flag_ONLY_ONE ) && i.typeId() == it.typeId() ) {
2936 return ret_val<bool>::make_failure( _( "Can't wear more than one %s!" ), it.tname() );
2937 }
2938 }
2939
2940 if( amount_worn( it.typeId() ) >= MAX_WORN_PER_TYPE ) {
2941 return ret_val<bool>::make_failure( _( "Can't wear %i or more %s at once." ),
2942 MAX_WORN_PER_TYPE + 1, it.tname( MAX_WORN_PER_TYPE + 1 ) );
2943 }
2944
2945 if( ( ( it.covers( bp_foot_l ) && is_wearing_shoes( side::LEFT ) ) ||
2946 ( it.covers( bp_foot_r ) && is_wearing_shoes( side::RIGHT ) ) ) &&
2947 ( !it.has_flag( flag_OVERSIZE ) || !it.has_flag( flag_OUTER ) ) && !it.has_flag( flag_SKINTIGHT ) &&
2948 !it.has_flag( flag_BELTED ) && !it.has_flag( flag_PERSONAL ) && !it.has_flag( flag_AURA ) &&
2949 !it.has_flag( flag_SEMITANGIBLE ) ) {
2950 // Checks to see if the player is wearing shoes
2951 return ret_val<bool>::make_failure( ( is_player() ? _( "You're already wearing footwear!" )
2952 : string_format( _( "%s is already wearing footwear!" ), name ) ) );
2953 }
2954
2955 if( it.covers( bp_head ) &&
2957 !it.has_flag( flag_PERSONAL ) && !it.is_power_armor() &&
2959 is_wearing_helmet() ) {
2961 ( is_player() ? _( "You can't wear that with other headgear!" )
2962 : string_format( _( "%s can't wear that with other headgear!" ), name ) ) );
2963 }
2964
2965 if( it.covers( bp_head ) && !it.has_flag( flag_SEMITANGIBLE ) &&
2967 ( head_cloth_encumbrance() + it.get_encumber( *this ) > 40 ) ) {
2968 return ret_val<bool>::make_failure( ( is_player() ? _( "You can't wear that much on your head!" )
2969 : string_format( _( "%s can't wear that much on their head!" ), name ) ) );
2970 }
2971
2973}
static const std::string flag_BELTED("BELTED")
static const trait_id trait_ANTLERS("ANTLERS")
static const trait_id trait_WOOLALLERGY("WOOLALLERGY")
static const trait_id trait_HORNS_POINTED("HORNS_POINTED")
static const std::string flag_SKINTIGHT("SKINTIGHT")
static const std::string flag_POWERARMOR_COMPATIBLE("POWERARMOR_COMPATIBLE")
static const trait_id trait_ANTENNAE("ANTENNAE")
static const std::string flag_HELMET_COMPAT("HELMET_COMPAT")
static const std::string flag_POWERARMOR_EXO("POWERARMOR_EXO")
static const std::string flag_OUTER("OUTER")
static const std::string flag_OVERSIZE("OVERSIZE")
static const std::string flag_ONLY_ONE("ONLY_ONE")
static const std::string flag_POWERARMOR_EXTERNAL("POWERARMOR_EXTERNAL")
static const std::string flag_RESTRICT_HANDS("RESTRICT_HANDS")
static const trait_id trait_SQUEAMISH("SQUEAMISH")
bool is_wearing_power_armor(bool *hasHelmet=nullptr) const
Returns true if the character is wearing power armor.
Definition: character.cpp:3807
bool is_wearing_helmet() const
Returns true if the character is wearing something occupying the helmet slot.
Definition: character.cpp:8900
int amount_worn(const itype_id &id) const
Returns the amount of item ‘type’ that is currently worn.
Definition: character.cpp:2187
bool has_two_arms() const
Returns true if the player has two functioning arms.
Definition: character.cpp:1220
int head_cloth_encumbrance() const
Returns the total encumbrance of all SKINTIGHT and HELMET_COMPAT items coveringi the head.
Definition: character.cpp:8912
bool is_wearing_shoes(const side &which_side=side::BOTH) const
Returns true if the player is wearing something on their feet that is not SKINTIGHT.
Definition: character.cpp:8871
bool is_sided() const
Returns true if item is armor and can be worn on different sides of the body.
Definition: item.cpp:805
const std::vector< material_id > & made_of() const
The ids of all the materials this is made of.
Definition: item.cpp:6438
bool is_filthy() const
Marks the item as filthy, so characters with squeamish trait can't wear it.
Definition: item.cpp:10010
std::string type_name(unsigned int quantity=1) const
Name of the item type (not the item), with proper plural.
Definition: item.cpp:9880
bool is_power_armor() const
Whether this is a power armor item.
Definition: item.cpp:5811
bool is_armor() const
Definition: item.cpp:6729
int get_encumber(const Character &) const
Returns the encumbrance value that this item has when worn by given player.
Definition: item.cpp:5817
bool is_two_handed(const Character &guy) const
Whether the character needs both hands to wield this item.
Definition: item.cpp:6429
static constexpr int MAX_WORN_PER_TYPE

References _, amount_worn(), BOTH, bp_foot_l, bp_foot_r, bp_head, bp_torso, convert_bp(), item::covers(), flag_AURA(), flag_BELTED(), flag_HELMET_COMPAT(), flag_ONLY_ONE(), flag_OUTER(), flag_OVERSIZE(), flag_PERSONAL(), flag_POWERARMOR_COMPATIBLE(), flag_POWERARMOR_EXO(), flag_POWERARMOR_EXTERNAL(), flag_POWERARMOR_MOD(), flag_RESTRICT_HANDS(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), flag_SPLINT(), Creature::get_all_body_parts(), item::get_covered_body_parts(), item::get_encumber(), get_mutations(), item::has_flag(), item::has_own_flag(), has_trait(), has_two_arms(), head_cloth_encumbrance(), item::is_armor(), item::is_filthy(), is_limb_broken(), Creature::is_player(), item::is_power_armor(), item::is_sided(), item::is_two_handed(), is_wearing_helmet(), is_wearing_power_armor(), is_wearing_shoes(), LEFT, item::made_of(), ret_val< T >::make_failure(), ret_val< T >::make_success(), MAX_WORN_PER_TYPE, name, num_bp, body_part_type::part_side, primary_weapon(), RIGHT, string_format(), body_part_set::test(), item::tname(), trait_ANTENNAE, trait_ANTLERS, trait_HORNS_POINTED, trait_SQUEAMISH, trait_WOOLALLERGY, item::type_name(), item::typeId(), wearing_something_on(), worn, and worn_with_flag().

Referenced by behavior::character_oracle_t::can_wear_warmer_clothes(), dispose_item(), wear_inventory_preset::get_denial(), give_item_to(), handle_problematic_pickup(), examine_item_menu::rate_action_wear(), spell_effect::spawn_ethereal_item(), starting_clothes(), avatar_funcs::use_item(), npc::wear_if_wanted(), and wear_item().

◆ can_wield()

ret_val< bool > Character::can_wield ( const item it) const

Check whether character is capable of wielding given item.

Definition at line 3089 of file character.cpp.

3090{
3091 if( it.made_of( LIQUID ) ) {
3092 return ret_val<bool>::make_failure( _( "Can't wield spilt liquids." ) );
3093 }
3094
3095 if( get_working_arm_count() <= 0 ) {
3097 _( "You need at least one arm to even consider wielding something." ) );
3098 }
3099
3100 const item &weapon = primary_weapon();
3101 if( is_armed() && weapon.has_flag( "NO_UNWIELD" ) ) {
3102 return ret_val<bool>::make_failure( _( "The %s is preventing you from wielding the %s." ),
3104 }
3105
3106 monster *mount = mounted_creature.get();
3107 if( it.is_two_handed( *this ) && ( !has_two_arms() || worn_with_flag( flag_RESTRICT_HANDS ) ) &&
3108 !( is_mounted() && mount->has_flag( MF_RIDEABLE_MECH ) &&
3109 mount->type->mech_weapon && it.typeId() == mount->type->mech_weapon ) ) {
3112 _( "Something you are wearing hinders the use of both hands." ) );
3113 } else if( it.has_flag( "ALWAYS_TWOHAND" ) ) {
3114 return ret_val<bool>::make_failure( _( "The %s can't be wielded with only one arm." ),
3115 it.tname() );
3116 } else {
3117 return ret_val<bool>::make_failure( _( "You are too weak to wield %s with only one arm." ),
3118 it.tname() );
3119 }
3120 }
3121
3123}
int get_working_arm_count() const
Returns the number of functioning arms.
Definition: character.cpp:1227
bool is_armed() const
Returns true if the character is wielding something.
Definition: melee.cpp:205
const mtype * type
Definition: monster.h:478
@ LIQUID
Definition: enums.h:175
std::string fmt_wielded_weapon(const Character &who)
Get the formatted name of the currently wielded item (if any) with current gun mode (if gun)
itype_id mech_weapon
If this monster is a rideable mech with built-in weapons, this is the weapons id.
Definition: mtype.h:368

References _, flag_RESTRICT_HANDS(), character_funcs::fmt_wielded_weapon(), get_working_arm_count(), item::has_flag(), monster::has_flag(), has_two_arms(), is_armed(), is_mounted(), item::is_two_handed(), LIQUID, item::made_of(), ret_val< T >::make_failure(), ret_val< T >::make_success(), mtype::mech_weapon, MF_RIDEABLE_MECH, mounted_creature, primary_weapon(), item::tname(), monster::type, item::typeId(), and worn_with_flag().

Referenced by apply_damage(), find_best_bench(), weapon_inventory_preset::get_denial(), pick_one_up(), character_funcs::try_wield_contents(), avatar::wield(), and avatar_action::wield().

◆ cancel_activity()

void Character::cancel_activity ( )

Definition at line 9234 of file character.cpp.

9235{
9236 activity.canceled( *this );
9237 if( has_activity( ACT_MOVE_ITEMS ) && is_hauling() ) {
9238 stop_hauling();
9239 }
9240 if( has_activity( ACT_TRY_SLEEP ) ) {
9241 remove_value( "sleep_query" );
9242 }
9243 // Clear any backlog items that aren't auto-resume.
9244 for( auto backlog_item = backlog.begin(); backlog_item != backlog.end(); ) {
9245 if( backlog_item->auto_resume ) {
9246 backlog_item++;
9247 } else {
9248 backlog_item = backlog.erase( backlog_item );
9249 }
9250 }
9251 // act wait stamina interrupts an ongoing activity.
9252 // and automatically puts auto_resume = true on it
9253 // we don't want that to persist if there is another interruption.
9254 // and player moves elsewhere.
9255 if( has_activity( ACT_WAIT_STAMINA ) && !backlog.empty() &&
9256 backlog.front().auto_resume ) {
9257 backlog.front().auto_resume = false;
9258 }
9259 if( activity && activity.is_suspendable() ) {
9260 backlog.push_front( activity );
9261 }
9262 sfx::end_activity_sounds(); // kill activity sounds when canceled
9264}
static const activity_id ACT_TRY_SLEEP("ACT_TRY_SLEEP")
static const activity_id ACT_MOVE_ITEMS("ACT_MOVE_ITEMS")
static const activity_id ACT_WAIT_STAMINA("ACT_WAIT_STAMINA")
bool is_hauling() const
Definition: character.cpp:9186
void stop_hauling()
Definition: character.cpp:9177
void canceled(Character &who)
Performs activity-specific cleanup when Character::cancel_activity() is called.
bool is_suspendable() const
If this returns true, the action can be continued without starting from scratch again (see player::ba...
void end_activity_sounds()
Definition: sounds.cpp:1603

References ACT_MOVE_ITEMS, ACT_TRY_SLEEP, ACT_WAIT_STAMINA, activity, backlog, player_activity::canceled(), sfx::end_activity_sounds(), has_activity(), is_hauling(), player_activity::is_suspendable(), Creature::remove_value(), and stop_hauling().

Referenced by activity_on_turn_move_loot(), activity_on_turn_wear(), activity_handlers::adv_inventory_do_turn(), activity_handlers::armor_layers_do_turn(), activity_handlers::build_do_turn(), player::can_continue_craft(), game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), activity_handlers::craft_do_turn(), autodrive_activity_actor::do_turn(), drop_activity_actor::do_turn(), stash_activity_actor::do_turn(), pickup_activity_actor::do_turn(), avatar_action::eat(), fall_asleep(), game::forced_door_closing(), item::handle_craft_failure(), mattack::pull_metal_weapon(), npc::reboot(), DefaultRemovePartHandler::removed(), show_armor_layers_ui(), autodrive_activity_actor::start(), activity_handlers::start_fire_do_turn(), stop_hauling(), and npc::talk_to_u().

◆ cancel_stashed_activity()

void Character::cancel_stashed_activity ( )

◆ change_side() [1/2]

bool Character::change_side ( item it,
bool  interactive = true 
)

Swap side on which item is worn; returns false on fail.

If interactive is false, don't alert player or drain moves

Definition at line 3719 of file character.cpp.

3720{
3721 const auto ret = can_swap( it );
3722 if( !ret.success() ) {
3723 if( interactive ) {
3724 add_msg_if_player( m_info, "%s", ret.c_str() );
3725 }
3726 return false;
3727 }
3728
3729 if( !it.swap_side() ) {
3730 if( interactive ) {
3732 _( "You cannot swap the side on which your %s is worn." ),
3733 _( "<npcname> cannot swap the side on which their %s is worn." ),
3734 it.tname() );
3735 }
3736 return false;
3737 }
3738
3739 if( interactive ) {
3740 add_msg_player_or_npc( m_info, _( "You swap the side on which your %s is worn." ),
3741 _( "<npcname> swaps the side on which their %s is worn." ),
3742 it.tname() );
3743 }
3744
3745 mod_moves( -250 );
3747
3748 return true;
3749}
ret_val< bool > can_swap(const item &it) const
Check player capable of swapping the side of a worn item.
Definition: character.cpp:3156
bool swap_side()
Swap the side on which the item is worn.
Definition: item.cpp:833

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), can_swap(), m_info, Creature::mod_moves(), reset_encumbrance(), cata::hash64_detail::ret, item::swap_side(), and item::tname().

Referenced by npc::adjust_worn(), change_side(), examine_item_menu::run(), and show_armor_layers_ui().

◆ change_side() [2/2]

bool Character::change_side ( item_location loc,
bool  interactive = true 
)

Definition at line 3751 of file character.cpp.

3752{
3753 if( !loc || !is_worn( *loc ) ) {
3754 if( interactive ) {
3756 _( "You are not wearing that item." ),
3757 _( "<npcname> isn't wearing that item." ) );
3758 }
3759 return false;
3760 }
3761
3762 return change_side( *loc, interactive );
3763}
bool is_worn(const item &thing) const
Definition: character.h:1099
bool change_side(item &it, bool interactive=true)
Swap side on which item is worn; returns false on fail.
Definition: character.cpp:3719

References _, Creature::add_msg_player_or_npc(), change_side(), is_worn(), and m_info.

◆ check_and_recover_morale()

bool Character::check_and_recover_morale ( )

Checks permanent morale for consistency and recovers it when an inconsistency is found.

Definition at line 9129 of file character.cpp.

9130{
9131 player_morale test_morale;
9132
9133 for( const item &wit : worn ) {
9134 test_morale.on_item_wear( wit );
9135 }
9136
9137 for( const trait_id &mut : get_mutations() ) {
9138 test_morale.on_mutation_gain( mut );
9139 }
9140
9141 for( const auto &elem : *effects ) {
9142 for( const std::pair<const bodypart_str_id, effect> &_effect_it : elem.second ) {
9143 const effect &e = _effect_it.second;
9144 if( !e.is_removed() ) {
9145 test_morale.on_effect_int_change( e.get_id(), e.get_intensity(), e.get_bp() );
9146 }
9147 }
9148 }
9149
9150 test_morale.on_stat_change( "kcal", get_stored_kcal() );
9151 test_morale.on_stat_change( "thirst", get_thirst() );
9152 test_morale.on_stat_change( "fatigue", get_fatigue() );
9153 test_morale.on_stat_change( "pain", get_pain() );
9154 test_morale.on_stat_change( "pkill", get_painkiller() );
9155 test_morale.on_stat_change( "perceived_pain", get_perceived_pain() );
9156
9158
9159 if( !morale->consistent_with( test_morale ) ) {
9160 *morale = player_morale( test_morale ); // Recover consistency
9161 add_msg( m_debug, "%s morale was recovered.", disp_name( true ) );
9162 return false;
9163 }
9164
9165 return true;
9166}
int get_fatigue() const
Definition: character.cpp:4479
int get_thirst() const
Definition: character.cpp:4351
void apply_persistent_morale()
Ensures persistent morale effects are up-to-date.
Definition: character.cpp:9008
pimpl< effects_map > effects
Definition: creature.h:820
const efftype_id & get_id() const
Returns the effect's matching effect_type id.
Definition: effect.h:305
int get_intensity() const
Returns the intensity of an effect.
Definition: effect.cpp:849
const bodypart_str_id & get_bp() const
Returns the targeted body_part of the effect.
Definition: effect.cpp:835
bool is_removed() const
Returns if the effect is disabled and set up for removal.
Definition: effect.h:246
void on_item_wear(const item &it)
Definition: morale.cpp:935
void on_stat_change(const std::string &stat, int value)
Definition: morale.cpp:927
void on_effect_int_change(const efftype_id &eid, int intensity, const bodypart_str_id &bp=bodypart_str_id::NULL_ID())
Definition: morale.cpp:974
void on_mutation_gain(const trait_id &mid)
Definition: morale.cpp:917

References add_msg(), apply_persistent_morale(), disp_name(), Creature::effects, effect::get_bp(), get_fatigue(), effect::get_id(), effect::get_intensity(), get_mutations(), Creature::get_pain(), get_painkiller(), get_perceived_pain(), get_stored_kcal(), get_thirst(), effect::is_removed(), m_debug, morale, player_morale::on_effect_int_change(), player_morale::on_item_wear(), player_morale::on_mutation_gain(), player_morale::on_stat_change(), and worn.

Referenced by process_turn().

◆ check_item_encumbrance_flag()

void Character::check_item_encumbrance_flag ( )

Checks worn items for the "RESET_ENCUMBRANCE" flag, which indicates that encumbrance may have changed and require recalculating.

Definition at line 1767 of file character.cpp.

1768{
1769 bool update_required = check_encumbrance;
1770 for( auto &i : worn ) {
1771 if( !update_required && i.encumbrance_update_ ) {
1772 update_required = true;
1773 }
1774 i.encumbrance_update_ = false;
1775 }
1776
1777 if( update_required ) {
1779 }
1780}
bool check_encumbrance
Definition: character.h:2261

References check_encumbrance, reset_encumbrance(), and worn.

◆ check_mount_is_spooked()

bool Character::check_mount_is_spooked ( )

Definition at line 1041 of file character.cpp.

1042{
1043 if( !is_mounted() ) {
1044 return false;
1045 }
1046 // chance to spook per monster nearby:
1047 // base 1% per turn.
1048 // + 1% per square closer than 15 distanace. (1% - 15%)
1049 // * 2 if hostile monster is bigger than or same size as mounted creature.
1050 // -0.25% per point of dexterity (low -1%, average -2%, high -3%, extreme -3.5%)
1051 // -0.1% per point of strength ( low -0.4%, average -0.8%, high -1.2%, extreme -1.4% )
1052 // / 2 if horse has full tack and saddle.
1053 // Monster in spear reach monster and average stat (8) player on saddled horse, 14% -2% -0.8% / 2 = ~5%
1054 if( mounted_creature && mounted_creature->type->has_fear_trigger( mon_trigger::HOSTILE_CLOSE ) ) {
1055 const m_size mount_size = mounted_creature->get_size();
1056 const bool saddled = mounted_creature->has_effect( effect_saddled );
1057 for( const monster &critter : g->all_monsters() ) {
1058 double chance = 1.0;
1059 Attitude att = critter.attitude_to( *this );
1060 // actually too close now - horse might spook.
1061 if( att == A_HOSTILE && sees( critter ) && rl_dist( pos(), critter.pos() ) <= 10 ) {
1062 chance += 10 - rl_dist( pos(), critter.pos() );
1063 if( critter.get_size() >= mount_size ) {
1064 chance *= 2;
1065 }
1066 chance -= 0.25 * get_dex();
1067 chance -= 0.1 * get_str();
1068 if( saddled ) {
1069 chance /= 2;
1070 }
1071 chance = std::max( 1.0, chance );
1072 if( x_in_y( chance, 100.0 ) ) {
1074 return true;
1075 }
1076 }
1077 }
1078 }
1079 return false;
1080}
bool x_in_y(const time_duration &a, const time_duration &b)
Definition: calendar.cpp:521
static const efftype_id effect_saddled("monster_saddled")
virtual int get_dex() const
Definition: character.cpp:4092
void forced_dismount()
Definition: character.cpp:1087
Attitude
Simplified attitude towards any creature: hostile - hate, want to kill, etc.
Definition: creature.h:166
m_size
Definition: creature.h:57

References Creature::A_HOSTILE, effect_saddled, forced_dismount(), g, get_dex(), get_str(), HOSTILE_CLOSE, is_mounted(), mounted_creature, pos(), rl_dist(), sees(), and x_in_y().

Referenced by game::do_turn().

◆ check_mount_will_move()

bool Character::check_mount_will_move ( const tripoint dest_loc)

Definition at line 1023 of file character.cpp.

1024{
1025 if( !is_mounted() ) {
1026 return true;
1027 }
1028 if( mounted_creature && mounted_creature->type->has_fear_trigger( mon_trigger::HOSTILE_CLOSE ) ) {
1029 for( const monster &critter : g->all_monsters() ) {
1030 Attitude att = critter.attitude_to( *this );
1031 if( att == A_HOSTILE && sees( critter ) && rl_dist( pos(), critter.pos() ) <= 15 &&
1032 rl_dist( dest_loc, critter.pos() ) < rl_dist( pos(), critter.pos() ) ) {
1033 add_msg_if_player( _( "You fail to budge your %s!" ), mounted_creature->get_name() );
1034 return false;
1035 }
1036 }
1037 }
1038 return true;
1039}

References _, Creature::A_HOSTILE, Creature::add_msg_if_player(), g, HOSTILE_CLOSE, is_mounted(), mounted_creature, pos(), rl_dist(), and sees().

Referenced by avatar_action::move().

◆ check_needs_extremes()

void Character::check_needs_extremes ( )

Kills the player if too hungry, stimmed up etc., forces tired player to sleep and prints warnings.

Intelligence slightly decreases occurrence of short naps when dead tired Intelligence slightly decreases occurrence of short naps when exhausted Perception slightly decreases occurrence of short naps when sleep deprived Perception slightly increases resilience against passing out from sleep deprivation

Definition at line 4996 of file character.cpp.

4997{
4998 // Check if we've overdosed... in any deadly way.
4999 if( get_stim() > 250 ) {
5000 add_msg_if_player( m_bad, _( "You have a sudden heart attack!" ) );
5001 g->events().send<event_type::dies_from_drug_overdose>( getID(), efftype_id() );
5002 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5003 } else if( get_stim() < -200 || get_painkiller() > 240 ) {
5004 add_msg_if_player( m_bad, _( "Your breathing stops completely." ) );
5005 g->events().send<event_type::dies_from_drug_overdose>( getID(), efftype_id() );
5006 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5007 } else if( has_effect( effect_jetinjector ) && get_effect_dur( effect_jetinjector ) > 40_minutes ) {
5008 if( !( has_trait( trait_NOPAIN ) ) ) {
5009 add_msg_if_player( m_bad, _( "Your heart spasms painfully and stops." ) );
5010 } else {
5011 add_msg_if_player( _( "Your heart spasms and stops." ) );
5012 }
5014 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5015 } else if( get_effect_dur( effect_adrenaline ) > 50_minutes ) {
5016 add_msg_if_player( m_bad, _( "Your heart spasms and stops." ) );
5018 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5019 } else if( get_effect_int( effect_drunk ) > 4 ) {
5020 add_msg_if_player( m_bad, _( "Your breathing slows down to a stop." ) );
5022 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5023 }
5024
5025 // check if we've starved
5026 if( is_player() ) {
5027 if( get_stored_kcal() <= 0 ) {
5028 add_msg_if_player( m_bad, _( "You have starved to death." ) );
5029 g->events().send<event_type::dies_of_starvation>( getID() );
5030 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5031 } else if( calendar::once_every( 6_hours ) ) {
5032 std::string category;
5033 if( get_kcal_percent() < 0.1f ) {
5034 category = "empty_starving";
5035 } else if( get_kcal_percent() < 0.25f ) {
5036 category = "empty_emaciated";
5037 } else if( get_kcal_percent() < 0.5f ) {
5038 category = "empty_malnutrition";
5039 } else if( get_kcal_percent() < 0.7f ) {
5040 category = "empty_low_cal";
5041 }
5042 if( !category.empty() ) {
5043 const translation message = SNIPPET.random_from_category( category ).value_or( translation() );
5045 }
5046
5047 }
5048 }
5049
5050 // Check if we're dying of thirst
5052 if( get_thirst() >= thirst_levels::dead ) {
5053 add_msg_if_player( m_bad, _( "You have died of dehydration." ) );
5054 g->events().send<event_type::dies_of_thirst>( getID() );
5055 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5056 } else if( get_thirst() >= lerp( +thirst_levels::parched, +thirst_levels::dead, 0.333f ) &&
5057 calendar::once_every( 30_minutes ) ) {
5058 add_msg_if_player( m_warning, _( "Even your eyes feel dry…" ) );
5059 } else if( get_thirst() >= lerp( +thirst_levels::parched, +thirst_levels::dead, 0.666f ) &&
5060 calendar::once_every( 30_minutes ) ) {
5061 add_msg_if_player( m_warning, _( "You are THIRSTY!" ) );
5062 } else if( calendar::once_every( 30_minutes ) ) {
5063 add_msg_if_player( m_warning, _( "Your mouth feels so dry…" ) );
5064 }
5065 }
5066
5067 // Check if we're falling asleep, unless we're sleeping
5070 add_msg_if_player( m_bad, _( "Survivor sleep now." ) );
5072 mod_fatigue( -10 );
5073 fall_asleep();
5074 } else if( get_fatigue() >= 800 && calendar::once_every( 30_minutes ) ) {
5075 add_msg_if_player( m_warning, _( "Anywhere would be a good place to sleep…" ) );
5076 } else if( calendar::once_every( 30_minutes ) ) {
5077 add_msg_if_player( m_warning, _( "You feel like you haven't slept in days." ) );
5078 }
5079 }
5080
5081 // Even if we're not Exhausted, we really should be feeling lack/sleep earlier
5082 // Penalties start at Dead Tired and go from there
5084 if( get_fatigue() >= 700 ) {
5085 if( calendar::once_every( 30_minutes ) ) {
5086 add_msg_if_player( m_warning, _( "You're too physically tired to stop yawning." ) );
5087 add_effect( effect_lack_sleep, 30_minutes + 1_turns );
5088 }
5089 /** @EFFECT_INT slightly decreases occurrence of short naps when dead tired */
5090 if( one_in( 50 + int_cur ) ) {
5091 fall_asleep( 30_seconds );
5092 }
5093 } else if( get_fatigue() >= fatigue_levels::exhausted ) {
5094 if( calendar::once_every( 30_minutes ) ) {
5095 add_msg_if_player( m_warning, _( "How much longer until bedtime?" ) );
5096 add_effect( effect_lack_sleep, 30_minutes + 1_turns );
5097 }
5098 /** @EFFECT_INT slightly decreases occurrence of short naps when exhausted */
5099 if( one_in( 100 + int_cur ) ) {
5100 fall_asleep( 30_seconds );
5101 }
5102 } else if( get_fatigue() >= fatigue_levels::dead_tired && calendar::once_every( 30_minutes ) ) {
5103 add_msg_if_player( m_warning, _( "*yawn* You should really get some sleep." ) );
5104 add_effect( effect_lack_sleep, 30_minutes + 1_turns );
5105 }
5106 }
5107
5108 // Sleep deprivation kicks in if lack of sleep is avoided with stimulants or otherwise for long periods of time
5110 float sleep_deprivation_pct = sleep_deprivation / static_cast<float>
5112
5114 calendar::once_every( 60_minutes ) &&
5118 _( "Your mind feels tired. It's been a while since you've slept well." ) );
5119 mod_fatigue( 1 );
5122 _( "Your mind feels foggy from lack of good sleep, and your eyes keep trying to close against your will." ) );
5123 mod_fatigue( 5 );
5124
5125 if( one_in( 10 ) ) {
5126 mod_healthy_mod( -1, 0 );
5127 }
5130 _( "Your mind feels weary, and you dread every wakeful minute that passes. You crave sleep, and feel like you're about to collapse." ) );
5131 mod_fatigue( 10 );
5132
5133 if( one_in( 5 ) ) {
5134 mod_healthy_mod( -2, -20 );
5135 }
5138 _( "You haven't slept decently for so long that your whole body is screaming for mercy. It's a miracle that you're still awake, but it just feels like a curse now." ) );
5139 mod_fatigue( 40 );
5140
5141 mod_healthy_mod( -5, -50 );
5142 }
5143 // else you pass out for 20 hours, guaranteed
5144
5145 // Microsleeps are slightly worse if you're sleep deprived, but not by much. (chance: 1 in (75 + per_cur) at minor sleep deprivation)
5146 // Note: these can coexist with fatigue-related microsleeps
5147 /** @EFFECT_PER slightly decreases occurrence of short naps when sleep deprived */
5148 if( one_in( static_cast<int>( ( 1.0f - sleep_deprivation_pct ) * 75 + get_per() ) ) ) {
5149 fall_asleep( 30_seconds );
5150 }
5151
5152
5155 /** @EFFECT_PER slightly increases resilience against passing out from sleep deprivation */
5156 one_in( static_cast<int>( ( 1.0f - sleep_deprivation_pct ) * 100 ) + get_per() ) ) ) ) {
5158 _( "Your body collapses due to sleep deprivation, your neglected fatigue rushing back all at once, and you pass out on the spot." )
5159 , _( "<npcname> collapses to the ground from exhaustion." ) );
5161 set_fatigue( static_cast<int>( fatigue_levels::exhausted ) );
5162 }
5163
5165 fall_asleep( 20_hours );
5167 fall_asleep( 16_hours );
5168 } else {
5169 fall_asleep( 12_hours );
5170 }
5171 }
5172 }
5173}
constexpr T lerp(const T &min, const T &max, float t)
Linear interpolation: returns first argument if t is 0, second if t is 1, otherwise proportional to t...
Definition: cata_utility.h:159
static const efftype_id effect_lack_sleep("lack_sleep")
static const efftype_id effect_drunk("drunk")
static const efftype_id effect_adrenaline("adrenaline")
static const efftype_id effect_meth("meth")
static const efftype_id effect_jetinjector("jetinjector")
static const trait_id trait_NOPAIN("NOPAIN")
float get_kcal_percent() const
Definition: character.cpp:4346
virtual void set_fatigue(int nfatigue)
Definition: character.cpp:4464
void fall_asleep()
Adds "sleep" to the player.
Definition: character.cpp:9274
virtual void mod_fatigue(int nfatigue)
Definition: character.cpp:4454
int get_stim() const
Definition: character.cpp:7053
virtual void mod_healthy_mod(int nhealthy_mod, int cap)
Definition: character.cpp:4282
int get_sleep_deprivation() const
Definition: character.cpp:4484
virtual int get_per() const
Definition: character.cpp:4096
void set_part_hp_cur(const bodypart_id &id, int set)
Definition: creature.cpp:1621
time_duration get_effect_dur(const efftype_id &eff_id, body_part bp=num_bp) const
Returns the duration of the matching effect.
Definition: creature.cpp:1281
std::optional< translation > random_from_category(const std::string &cat) const
Returns a random snippet out of the given category.
Class for storing translation context and raw string for deferred translation.
Definition: translations.h:152
@ m_warning
Definition: enums.h:264
@ falls_asleep_from_exhaustion
@ dies_from_drug_overdose
@ dies_of_starvation
bool once_every(const time_duration &event_frequency)
Predicate to handle rate-limiting.
Definition: calendar.cpp:490
std::string message
Definition: mapgen.cpp:411
snippet_library SNIPPET

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), dead, dead_tired, dies_from_drug_overdose, dies_of_starvation, dies_of_thirst, effect_adrenaline, effect_drunk, effect_jetinjector, effect_lack_sleep, effect_meth, efftype_id, exhausted, fall_asleep(), falls_asleep_from_exhaustion, g, Creature::get_effect_dur(), Creature::get_effect_int(), get_fatigue(), get_kcal_percent(), get_painkiller(), get_per(), get_sleep_deprivation(), get_stim(), get_stored_kcal(), get_thirst(), getID(), harmless, Creature::has_effect(), has_trait(), in_sleep_state(), int_cur, Creature::is_player(), lerp(), m_bad, m_warning, major, massive, mapgen_defer::message, minor, mod_fatigue(), mod_healthy_mod(), calendar::once_every(), one_in(), parched, snippet_library::random_from_category(), serious, set_fatigue(), Creature::set_part_hp_cur(), sleep_deprivation, SNIPPET, and trait_NOPAIN.

Referenced by update_body().

◆ check_outbounds_activity()

bool Character::check_outbounds_activity ( const player_activity act,
bool  check_only = false 
)

Definition at line 931 of file character.cpp.

932{
933 map &here = get_map();
934 if( ( act.placement != tripoint_zero && act.placement != tripoint_min &&
935 !here.inbounds( here.getlocal( act.placement ) ) ) || ( !act.coords.empty() &&
936 !here.inbounds( here.getlocal( act.coords.back() ) ) ) ) {
937 if( is_npc() && !check_only ) {
938 // stash activity for when reloaded.
940 if( !backlog.empty() ) {
942 }
944 }
946 "npc %s at pos %d %d, activity target is not inbounds at %d %d therefore activity was stashed",
947 disp_name(), pos().x, pos().y, act.placement.x, act.placement.y );
948 return true;
949 }
950 return false;
951}
tripoint getlocal(const tripoint &p) const
Inverse of getabs.
Definition: map.cpp:8416
virtual bool inbounds(const tripoint &p) const
Definition: map.cpp:7902
static constexpr tripoint tripoint_zero
Definition: point.h:259
static constexpr tripoint tripoint_min
Definition: point.h:304

References act, activity, add_msg(), backlog, disp_name(), get_map(), map::getlocal(), map::inbounds(), Creature::is_npc(), m_debug, pos(), stashed_outbounds_activity, stashed_outbounds_backlog, tripoint_min, and tripoint_zero.

Referenced by player_activity::do_turn(), and npc::move().

◆ clairvoyance()

int Character::clairvoyance ( ) const

Returns the distance the player can see through walls.

Definition at line 689 of file character.cpp.

690{
692 return MAX_CLAIRVOYANCE;
693 }
694
696 return 8;
697 }
698
700 return 3;
701 }
702
703 // 0 would mean we have clairvoyance of own tile
704 return -1;
705}
@ VISION_CLAIRVOYANCE_PLUS
@ VISION_CLAIRVOYANCE_SUPER
std::bitset< NUM_VISION_MODES > vision_mode_cache
Definition: character.h:2182

References VISION_CLAIRVOYANCE, VISION_CLAIRVOYANCE_PLUS, VISION_CLAIRVOYANCE_SUPER, and vision_mode_cache.

Referenced by sees().

◆ clear_bionics()

void Character::clear_bionics ( )

Remove all bionics.

Definition at line 2732 of file bionics.cpp.

2733{
2734 my_bionics->clear();
2735}

References my_bionics.

◆ clear_destination()

◆ clear_destination_activity()

void Character::clear_destination_activity ( )

Definition at line 958 of file character.cpp.

959{
961}
player_activity destination_activity
Definition: character.h:2246

References destination_activity.

Referenced by clear_destination().

◆ clear_miss_reasons()

void Character::clear_miss_reasons ( )

Clears the list of reasons for why the player would miss a melee attack.

Definition at line 384 of file melee.cpp.

385{
386 melee_miss_reasons.clear();
387}

References melee_miss_reasons.

Referenced by process_turn().

◆ clear_morale()

void Character::clear_morale ( )

Definition at line 9119 of file character.cpp.

9120{
9121 morale->clear();
9122}

References morale.

◆ clear_mutations()

void Character::clear_mutations ( )

Empties the trait and mutations lists.

Definition at line 2885 of file newcharacter.cpp.

2886{
2887 while( !my_traits.empty() ) {
2888 toggle_trait( *my_traits.begin() );
2889 }
2890 while( !my_mutations.empty() ) {
2891 unset_mutation( my_mutations.begin()->first );
2892 }
2893 cached_mutations.clear();
2894}
void toggle_trait(const trait_id &)
Toggles a trait on the player and in their mutation list.
Definition: mutation.cpp:125
std::vector< const mutation_branch * > cached_mutations
Pointers to mutation branches in my_mutations.
Definition: character.h:2168
void unset_mutation(const trait_id &)
Definition: mutation.cpp:165
std::unordered_set< trait_id > my_traits
Contains mutation ids of the base traits.
Definition: character.h:2164

References cached_mutations, my_mutations, my_traits, toggle_trait(), and unset_mutation().

Referenced by npc::randomize(), and reset_scenario().

◆ clear_npc_ai_info_cache()

void Character::clear_npc_ai_info_cache ( npc_ai_info  key) const

◆ clear_skills()

void Character::clear_skills ( )

Clear the skills map, setting all levels to 0.

Definition at line 2896 of file newcharacter.cpp.

2897{
2898 for( auto &sk : *_skills ) {
2899 sk.second.level( 0 );
2900 }
2901}
pimpl< SkillLevelMap > _skills
Character skills.
Definition: character.h:2175

References _skills.

Referenced by reset_scenario().

◆ compute_effective_nutrients()

nutrients Character::compute_effective_nutrients ( const item comest) const

Definition at line 335 of file consumption.cpp.

336{
337 if( !comest.is_comestible() ) {
338 return {};
339 }
340
341 // if item has components, will derive calories from that instead.
342 if( !comest.components.empty() && !comest.has_flag( flag_NUTRIENT_OVERRIDE ) ) {
343 nutrients tally{};
344 for( const item &component : comest.components ) {
345 nutrients component_value =
347 if( component.has_flag( flag_BYPRODUCT ) ) {
348 tally -= component_value;
349 } else {
350 tally += component_value;
351 }
352 }
353 return tally / comest.recipe_charges;
354 } else {
355 return compute_default_effective_nutrients( comest, *this );
356 }
357}
std::list< item > components
Definition: item.h:2162
int recipe_charges
Definition: item.h:2202
static nutrients compute_default_effective_nutrients(const item &comest, const Character &you, const cata::flat_set< std::string > &extra_flags={})
static const std::string flag_NUTRIENT_OVERRIDE("NUTRIENT_OVERRIDE")
static const std::string flag_BYPRODUCT("BYPRODUCT")

References item::components, compute_default_effective_nutrients(), compute_effective_nutrients(), flag_BYPRODUCT(), flag_NUTRIENT_OVERRIDE(), item::has_flag(), item::is_comestible(), and item::recipe_charges.

Referenced by can_eat(), comestible_inventory_preset::comestible_inventory_preset(), compute_effective_nutrients(), consume_effects(), eat(), item::food_info(), nutrition_for(), and will_eat().

◆ compute_nutrient_range() [1/2]

std::pair< nutrients, nutrients > Character::compute_nutrient_range ( const item comest,
const recipe_id recipe_i,
const cata::flat_set< std::string > &  extra_flags = {} 
) const

Get calorie & vitamin contents for a comestible, taking into account character traits.

Get range of possible nutrient content, for a particular recipe, depending on choice of ingredients

Definition at line 361 of file consumption.cpp.

364{
365 if( !comest.is_comestible() ) {
366 return {};
367 }
368
369 // if item has components, will derive calories from that instead.
370 if( comest.has_flag( flag_NUTRIENT_OVERRIDE ) ) {
372 return { result, result };
373 }
374
375 nutrients tally_min;
376 nutrients tally_max;
377
378 const recipe &rec = *recipe_i;
379
380 cata::flat_set<std::string> our_extra_flags = extra_flags;
381
382 if( rec.hot_result() || rec.dehydrate_result() ) {
383 our_extra_flags.insert( flag_COOKED );
384 }
385
386 const requirement_data requirements = rec.simple_requirements();
387 const requirement_data::alter_item_comp_vector &component_requirements =
388 requirements.get_components();
389
390 for( const std::vector<item_comp> &component_options : component_requirements ) {
391 nutrients this_min;
392 nutrients this_max;
393 bool first = true;
394 for( const item_comp &component_option : component_options ) {
395 std::pair<nutrients, nutrients> component_option_range =
396 compute_nutrient_range( component_option.type, our_extra_flags );
397 component_option_range.first *= component_option.count;
398 component_option_range.second *= component_option.count;
399
400 if( first ) {
401 std::tie( this_min, this_max ) = component_option_range;
402 first = false;
403 } else {
404 this_min.min_in_place( component_option_range.first );
405 this_max.max_in_place( component_option_range.second );
406 }
407 }
408 tally_min += this_min;
409 tally_max += this_max;
410 }
411
412 for( const std::pair<const itype_id, int> &byproduct : rec.byproducts ) {
413 item byproduct_it( byproduct.first, calendar::turn, byproduct.second );
414 nutrients byproduct_nutr = compute_default_effective_nutrients( byproduct_it, *this );
415 tally_min -= byproduct_nutr;
416 tally_max -= byproduct_nutr;
417 }
418
419 int charges = comest.count();
420 return { tally_min / charges, tally_max / charges };
421}
std::pair< nutrients, nutrients > compute_nutrient_range(const item &, const recipe_id &, const cata::flat_set< std::string > &extra_flags={}) const
Get calorie & vitamin contents for a comestible, taking into account character traits.
iterator insert(iterator, const value_type &value)
Definition: flat_set.h:151
int count() const
If count_by_charges(), returns charges, otherwise 1.
Definition: item.cpp:6035
Definition: recipe.h:35
const requirement_data & simple_requirements() const
Fetch combined requirement data (inline and via "using" syntax).
Definition: recipe.h:69
bool dehydrate_result() const
Definition: recipe.cpp:837
bool hot_result() const
Definition: recipe.cpp:810
std::map< itype_id, int > byproducts
Definition: recipe.h:107
static const std::string flag_COOKED("COOKED")
void min_in_place(const nutrients &r)
Replace the values here with the minimum (or maximum) of themselves and the corresponding values take...
Definition: stomach.cpp:12
void max_in_place(const nutrients &r)
Definition: stomach.cpp:29
The *_vector members represent list of alternatives requirements: alter_tool_comp_vector = { * { { a,...
Definition: requirements.h:215
const alter_item_comp_vector & get_components() const
std::vector< std::vector< item_comp > > alter_item_comp_vector
Definition: requirements.h:223

References recipe::byproducts, compute_default_effective_nutrients(), compute_nutrient_range(), item::count(), recipe::dehydrate_result(), flag_COOKED(), flag_NUTRIENT_OVERRIDE(), requirement_data::get_components(), item::has_flag(), recipe::hot_result(), cata::flat_set< T, Compare, Data >::insert(), item::is_comestible(), nutrients::max_in_place(), nutrients::min_in_place(), recipe::simple_requirements(), and calendar::turn.

Referenced by compute_nutrient_range(), and item::food_info().

◆ compute_nutrient_range() [2/2]

std::pair< nutrients, nutrients > Character::compute_nutrient_range ( const itype_id comest_id,
const cata::flat_set< std::string > &  extra_flags = {} 
) const

Same, but across arbitrary recipes.

Definition at line 425 of file consumption.cpp.

427{
428 const itype *comest = &*comest_id;
429 if( !comest->comestible ) {
430 return {};
431 }
432
433 item comest_it( comest, calendar::turn, 1 );
434 // The default nutrients are always a possibility
435 nutrients min_nutr = compute_default_effective_nutrients( comest_it, *this, extra_flags );
436
437 if( comest->has_flag( flag_NUTRIENT_OVERRIDE ) ||
438 recipe_dict.is_item_on_loop( comest->get_id() ) ) {
439 return { min_nutr, min_nutr };
440 }
441
442 nutrients max_nutr = min_nutr;
443
444 for( const recipe_id &rec : comest->recipes ) {
445 nutrients this_min;
446 nutrients this_max;
447
448 item result_it = rec->create_result();
449 if( result_it.contents.num_item_stacks() == 1 ) {
450 const item alt_result = result_it.contents.front();
451 if( alt_result.typeId() == comest_it.typeId() ) {
452 result_it = alt_result;
453 }
454 }
455 if( result_it.typeId() != comest_it.typeId() ) {
456 debugmsg( "When creating recipe result expected %s, got %s\n",
457 comest_it.typeId().str(), result_it.typeId().str() );
458 }
459 std::tie( this_min, this_max ) = compute_nutrient_range( result_it, rec, extra_flags );
460 min_nutr.min_in_place( this_min );
461 max_nutr.max_in_place( this_max );
462 }
463
464 return { min_nutr, max_nutr };
465}
size_t num_item_stacks() const
returns the number of items stacks in contents each item that is not count_by_charges,...
bool is_item_on_loop(const itype_id &) const
item create_result() const
Definition: recipe.cpp:459
recipe_dictionary recipe_dict
cata::value_ptr< islot_comestible > comestible
Definition: itype.h:818
std::vector< recipe_id > recipes
What recipes can make this item.
Definition: itype.h:982
bool has_flag(const std::string &flag) const
Definition: itype.cpp:146
const itype_id & get_id() const
Definition: itype.cpp:88

References itype::comestible, compute_default_effective_nutrients(), compute_nutrient_range(), item::contents, recipe::create_result(), debugmsg, flag_NUTRIENT_OVERRIDE(), item_contents::front(), itype::get_id(), itype::has_flag(), recipe_dictionary::is_item_on_loop(), nutrients::max_in_place(), nutrients::min_in_place(), item_contents::num_item_stacks(), recipe_dict, itype::recipes, string_id< T >::str(), calendar::turn, and item::typeId().

◆ conduct_blood_analysis()

void Character::conduct_blood_analysis ( ) const

Definition at line 1961 of file character.cpp.

1962{
1963 std::vector<std::string> effect_descriptions;
1964 std::vector<nc_color> colors;
1965
1966 for( auto &elem : *effects ) {
1967 if( elem.first->get_blood_analysis_description().empty() ) {
1968 continue;
1969 }
1970 effect_descriptions.emplace_back( elem.first->get_blood_analysis_description() );
1971 colors.emplace_back( elem.first->get_rating() == e_good ? c_green : c_red );
1972 }
1973
1974 const int win_w = 46;
1975 size_t win_h = 0;
1977 ui_adaptor ui;
1978 ui.on_screen_resize( [&]( ui_adaptor & ui ) {
1979 win_h = std::min( static_cast<size_t>( TERMY ),
1980 std::max<size_t>( 1, effect_descriptions.size() ) + 2 );
1981 w = catacurses::newwin( win_h, win_w,
1982 point( ( TERMX - win_w ) / 2, ( TERMY - win_h ) / 2 ) );
1983 ui.position_from_window( w );
1984 } );
1985 ui.mark_resize();
1986 ui.on_redraw( [&]( const ui_adaptor & ) {
1987 draw_border( w, c_red, string_format( " %s ", _( "Blood Test Results" ) ) );
1988 if( effect_descriptions.empty() ) {
1989 trim_and_print( w, point( 2, 1 ), win_w - 3, c_white, _( "No effects." ) );
1990 } else {
1991 for( size_t line = 1; line < ( win_h - 1 ) && line <= effect_descriptions.size(); ++line ) {
1992 trim_and_print( w, point( 2, line ), win_w - 3, colors[line - 1], effect_descriptions[line - 1] );
1993 }
1994 }
1995 wnoutrefresh( w );
1996 } );
1997 input_context ctxt( "BLOOD_TEST_RESULTS" );
1998 ctxt.register_action( "CONFIRM" );
1999 ctxt.register_action( "QUIT" );
2000 ctxt.register_action( "HELP_KEYBINDINGS" );
2001 bool stop = false;
2002 // Display new messages
2003 g->invalidate_main_ui_adaptor();
2004 while( !stop ) {
2006 const std::string action = ctxt.handle_input();
2007 if( action == "CONFIRM" || action == "QUIT" ) {
2008 stop = true;
2009 }
2010 }
2011}
A wrapper over a pointer to a curses window.
Definition: cursesdef.h:55
Represents a context in which a set of actions can be performed.
Definition: input.h:382
Adaptor between UI code and the UI management system.
Definition: ui_manager.h:65
@ action
Definition: dialogue.h:36
@ e_good
Definition: effect.h:29
void line(map *m, const ter_id &type, point p1, point p2)
Definition: mapgen.cpp:6281
std::string colors()
Definition: path_info.cpp:146
window newwin(int nlines, int ncols, point begin)
Definition: ncurses_def.cpp:34
void wnoutrefresh(const window &win)
Definition: ncurses_def.cpp:43
void redraw()
Invalidate the top window and redraw all invalidated windows.
Definition: ui_manager.cpp:389
Definition: overmap_ui.h:17
int TERMX
Definition: output.cpp:47
int TERMY
Definition: output.cpp:48
void trim_and_print(const catacurses::window &w, point begin, const int width, const nc_color &base_color, const std::string &text, const report_color_error color_error)
Prints a single line of text.
Definition: output.cpp:214
void draw_border(const catacurses::window &w, nc_color border_color, const std::string &title, nc_color title_color)
Definition: output.cpp:575

References _, action, c_green, c_red, c_white, PATH_INFO::colors(), draw_border(), e_good, Creature::effects, g, input_context::handle_input(), line(), catacurses::newwin(), ui_manager::redraw(), input_context::register_action(), string_format(), TERMX, TERMY, trim_and_print(), and catacurses::wnoutrefresh().

Referenced by activate_bionic(), and iexamine::autodoc().

◆ consume()

void Character::consume ( item_location  loc)

Consume item (food, fuel, medicine, ...) at given location loc .

Definition at line 1548 of file consumption.cpp.

1549{
1550 item &target = *loc;
1551 const bool wielding = is_wielding( target );
1552 const bool worn = is_worn( target );
1553 const bool inv_item = !( wielding || worn );
1554
1555 if( consume_item( target ) ) {
1556
1557 const bool was_in_container = !can_consume_as_is( target );
1558
1559 if( was_in_container ) {
1560 i_rem( &target.contents.front() );
1561 } else {
1562 i_rem( &target );
1563 }
1564
1565 // Restack and sort so that we don't lie about target's invlet
1566 if( inv_item ) {
1567 inv.restack( *this->as_player() );
1568 }
1569
1570 if( was_in_container && wielding ) {
1571 add_msg_if_player( _( "You are now wielding an empty %s." ), primary_weapon().tname() );
1572 } else if( was_in_container && worn ) {
1573 add_msg_if_player( _( "You are now wearing an empty %s." ), target.tname() );
1574 } else if( was_in_container && !is_npc() ) {
1575 bool drop_it = false;
1576 if( get_option<std::string>( "DROP_EMPTY" ) == "no" ) {
1577 drop_it = false;
1578 } else if( get_option<std::string>( "DROP_EMPTY" ) == "watertight" ) {
1579 drop_it = !target.is_watertight_container();
1580 } else if( get_option<std::string>( "DROP_EMPTY" ) == "all" ) {
1581 drop_it = true;
1582 }
1583 if( drop_it ) {
1584 add_msg( _( "You drop the empty %s." ), target.tname() );
1586 } else {
1587 int quantity = inv.const_stack( inv.position_by_item( &target ) ).size();
1588 char letter = target.invlet ? target.invlet : ' ';
1589 add_msg( m_info, _( "%c - %d empty %s" ), letter, quantity, target.tname( quantity ) );
1590 }
1591 }
1592 } else if( inv_item ) {
1593 if( pickup::handle_spillable_contents( *this, target, g->m ) ) {
1594 i_rem( &target );
1595 }
1596 inv.restack( *this->as_player() );
1597 inv.unsort();
1598 }
1599}
bool consume_item(item &target)
Consume given item (food, fuel, medicine, ...).
bool is_wielding(const item &target) const
Definition: character.cpp:3229
void restack(player &p)
Definition: inventory.cpp:399
void unsort()
Definition: inventory.cpp:227
item remove_item(const item *it)
Remove a specific item from the inventory.
Definition: inventory.cpp:718
const std::list< item > & const_stack(int i) const
Definition: inventory.cpp:152
int position_by_item(const item *it) const
Returns the item position of the stack that contains the given item (compared by pointers).
Definition: inventory.cpp:829
bool is_watertight_container() const
Whether this is a container which can be used to store liquids.
Definition: item.cpp:6749
bool handle_spillable_contents(Character &c, item &it, map &m)
If character is handling a potentially spillable bucket, gracefully handle what to do with the conten...
Definition: pickup.cpp:1246

References _, add_msg(), Creature::add_msg_if_player(), Creature::as_player(), can_consume_as_is(), inventory::const_stack(), consume_item(), item::contents, deliberate, item_contents::front(), g, pickup::handle_spillable_contents(), i_rem(), inv, item::invlet, Creature::is_npc(), item::is_watertight_container(), is_wielding(), is_worn(), m_info, inventory::position_by_item(), primary_weapon(), put_into_vehicle_or_drop(), inventory::remove_item(), inventory::restack(), item::tname(), inventory::unsort(), and worn.

Referenced by npc::consume_cbm_items(), npc::consume_food(), avatar_action::eat(), avatar_funcs::use_item(), and npc::use_painkiller().

◆ consume_charges()

bool Character::consume_charges ( item used,
int  qty 
)

Consume charges of a tool or comestible item, potentially destroying it in the process.

Parameters
useditem consuming the charges
qtynumber of charges to consume which must be non-zero
Returns
true if item was destroyed

Definition at line 7413 of file character.cpp.

7414{
7415 if( qty < 0 ) {
7416 debugmsg( "Tried to consume negative charges" );
7417 return false;
7418 }
7419
7420 if( qty == 0 ) {
7421 return false;
7422 }
7423
7424 if( !used.is_tool() && !used.is_food() && !used.is_medication() ) {
7425 debugmsg( "Tried to consume charges for non-tool, non-food, non-med item" );
7426 return false;
7427 }
7428
7429 // Consume comestibles destroying them if no charges remain
7430 if( used.is_food() || used.is_medication() ) {
7431 used.charges -= qty;
7432 if( used.charges <= 0 ) {
7433 i_rem( &used );
7434 return true;
7435 }
7436 return false;
7437 }
7438
7439 // Tools which don't require ammo are instead destroyed
7440 if( used.is_tool() && !used.ammo_required() ) {
7441 i_rem( &used );
7442 return true;
7443 }
7444
7445 if( used.is_power_armor() ) {
7446 if( used.charges >= qty ) {
7447 used.ammo_consume( qty, pos() );
7448 } else if( character_funcs::can_interface_armor( *this ) && has_charges( itype_bio_armor, qty ) ) {
7450 } else {
7451 use_charges( itype_UPS, qty );
7452 }
7453 }
7454
7455 // USE_UPS never occurs on base items but is instead added by the UPS tool mod
7456 if( used.has_flag( flag_USE_UPS ) ) {
7457 // With the new UPS system, we'll want to use any charges built up in the tool before pulling from the UPS
7458 // The usage of the item was already approved, so drain item if possible, otherwise use UPS
7459 if( used.charges >= qty ) {
7460 used.ammo_consume( qty, pos() );
7461 } else {
7462 use_charges( itype_UPS, qty );
7463 }
7464 } else {
7465 used.ammo_consume( std::min( qty, used.ammo_remaining() ), pos() );
7466 }
7467 return false;
7468}
static const itype_id itype_UPS("UPS")
static const std::string flag_USE_UPS("USE_UPS")
static const itype_id itype_bio_armor("bio_armor")
std::list< item > use_charges(const itype_id &what, int qty, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: character.cpp:9663
int ammo_remaining() const
Quantity of ammunition currently loaded in tool, gun or auxiliary gunmod.
Definition: item.cpp:7399
bool is_tool() const
Definition: item.cpp:6983
int ammo_required() const
Quantity of ammunition consumed per usage of tool or with each shot of gun.
Definition: item.cpp:7469
bool is_food() const
Definition: item.cpp:6617
int ammo_consume(int qty, const tripoint &pos)
Consume ammo (if available) and return the amount of ammo that was consumed.
Definition: item.cpp:7497
bool can_interface_armor(const Character &who)
Check whether character has an active bionic capable of interfacing with power armor.

References item::ammo_consume(), item::ammo_remaining(), item::ammo_required(), character_funcs::can_interface_armor(), item::charges, debugmsg, flag_USE_UPS(), has_charges(), item::has_flag(), i_rem(), item::is_food(), item::is_medication(), item::is_power_armor(), item::is_tool(), itype_bio_armor, itype_UPS, pos(), and use_charges().

Referenced by chop_plank_activity(), chop_tree_activity(), feedpet(), activity_handlers::firstaid_finish(), npc::heal_player(), npc::heal_self(), invoke_item(), activity_handlers::jackhammer_finish(), petfood(), activity_handlers::pickaxe_finish(), npc::pretend_heal(), activity_handlers::repair_item_finish(), activity_handlers::shear_finish(), activity_handlers::spellcasting_finish(), and activity_handlers::start_fire_finish().

◆ consume_effects()

bool Character::consume_effects ( item food)

Handles the effects of consuming an item.

Definition at line 1179 of file consumption.cpp.

1180{
1181 if( !food.is_comestible() ) {
1182 debugmsg( "called Character::consume_effects with non-comestible" );
1183 return false;
1184 }
1185
1186 if( has_trait( trait_THRESH_PLANT ) && food.type->can_use( "PLANTBLECH" ) ) {
1187 // Was used to cap nutrition and thirst, but no longer does this
1188 return false;
1189 }
1192 // No good can come of this.
1193 return false;
1194 }
1195
1196 const auto &comest = *food.get_comestible();
1197
1198 // Rotten food causes health loss
1199 const float relative_rot = food.get_relative_rot();
1200 if( relative_rot > 1.0f && !has_trait( trait_SAPROPHAGE ) &&
1202 const float rottedness = clamp( 2 * relative_rot - 2.0f, 0.1f, 1.0f );
1203 // ~-1 health per 1 nutrition at halfway-rotten-away, ~0 at "just got rotten"
1204 // But always round down
1205 int h_loss = -rottedness * comest.get_default_nutr();
1206 mod_healthy_mod( h_loss, -200 );
1207 add_msg( m_debug, "%d health from %0.2f%% rotten food", h_loss, rottedness );
1208 }
1209
1210 // Used in hibernation messages.
1211 const auto nutr = nutrition_for( food );
1212 const bool skip_health = has_trait( trait_PROJUNK2 ) && comest.healthy < 0;
1213 // We can handle junk just fine
1214 if( !skip_health ) {
1215 modify_health( comest );
1216 }
1217 modify_stimulation( comest );
1218 modify_fatigue( comest );
1219 modify_radiation( comest );
1220 modify_addiction( comest );
1221 modify_morale( food, nutr );
1222
1223 // Moved here and changed a bit - it was too complex
1224 // Incredibly minor stuff like this shouldn't require complexity
1225 if( !is_npc() && has_trait( trait_SLIMESPAWNER ) &&
1228 _( "You feel as though you're going to split open! In a good way?" ) );
1229 mod_pain( 5 );
1230 int numslime = 1;
1231 for( int i = 0; i < numslime; i++ ) {
1232 if( monster *const slime = g->place_critter_around( mon_player_blob, pos(), 1 ) ) {
1233 slime->friendly = -1;
1234 }
1235 }
1236 mod_stored_kcal( -400 );
1237 mod_thirst( 40 );
1238 //~ slimespawns have *small voices* which may be the Nice equivalent
1239 //~ of the Rat King's ALL CAPS invective. Probably shared-brain telepathy.
1240 add_msg_if_player( m_good, _( "hey, you look like me! let's work together!" ) );
1241 }
1242
1243 // Set up food for ingestion
1244 const item &contained_food = food.is_container() ? food.get_contained() : food;
1245 food_summary ingested{
1246 compute_effective_nutrients( contained_food )
1247 };
1248 // Maybe move tapeworm to digestion
1249 if( has_effect( effect_tapeworm ) ) {
1250 ingested.nutr /= 2;
1251 }
1252
1253 int excess_kcal = get_stored_kcal() + stomach.get_calories() + ingested.nutr.kcal -
1255
1256 // Moved hypermetabolism check here to prevent it being gimped by various bloating/vomit problems.
1257 if( excess_kcal > 0 && has_trait( trait_EATHEALTH ) ) {
1258 healall( roll_remainder( excess_kcal / 50.0f ) );
1259 mod_stored_kcal( -excess_kcal );
1260 excess_kcal = 0;
1261 }
1262
1263 int excess_quench = -( get_thirst() - comest.quench );
1264 stomach.ingest( ingested );
1265 mod_thirst( -contained_food.type->comestible->quench );
1266
1267
1268 if( ( excess_kcal > 0 || excess_quench > 0 ) && !food.has_flag( flag_NO_BLOAT ) &&
1270 add_effect( effect_bloated, 5_minutes );
1271 }
1272
1273 return true;
1274}
constexpr T clamp(const T &val, const T &min, const T &max)
Clamp first argument so that it is no lower than second and no higher than third.
Definition: cata_utility.h:149
void modify_addiction(const islot_comestible &comest)
Used to apply addiction modifications from food and medication.
void modify_stimulation(const islot_comestible &comest)
Used to apply stimulation modifications from food and medication.
void modify_morale(item &food, int nutr=0)
Used to apply morale modifications from food and medication.
void modify_radiation(const islot_comestible &comest)
Used to apply radiation from food and medication.
virtual void mod_thirst(int nthirst)
Definition: character.cpp:4438
stomach_contents stomach
Definition: character.h:1590
void modify_health(const islot_comestible &comest)
Used to apply health modifications from food and medication.
int nutrition_for(const item &comest) const
Handles the nutrition value for a comestible.
void healall(int dam)
Heals all body parts for dam.
Definition: character.cpp:8655
void modify_fatigue(const islot_comestible &comest)
Used to apply fatigue modifications from food and medication.
bool is_container() const
Whether this is container.
Definition: item.cpp:6744
double get_relative_rot() const
Get rot value relative to shelf life (or 0 if item does not spoil)
Definition: item.cpp:5556
const item & get_contained() const
Return a contained item (if any and only one).
Definition: item.cpp:7076
void ingest(const food_summary &ingested)
Directly adds food to stomach contents.
Definition: stomach.cpp:126
int get_calories() const
Definition: stomach.cpp:179
static const trait_id trait_SLIMESPAWNER("SLIMESPAWNER")
static const mtype_id mon_player_blob("mon_player_blob")
static const trait_id trait_THRESH_PLANT("THRESH_PLANT")
static const bionic_id bio_digestion("bio_digestion")
static const efftype_id effect_tapeworm("tapeworm")
static const trait_id trait_PROJUNK2("PROJUNK2")
static const trait_id trait_SAPROVORE("SAPROVORE")
static const efftype_id effect_bloated("bloated")
static const trait_id trait_EATHEALTH("EATHEALTH")
static const trait_id trait_GOURMAND("GOURMAND")
static const trait_id trait_SAPROPHAGE("SAPROPHAGE")
static const std::string flag_NO_BLOAT("NO_BLOAT")
bool can_use(const std::string &iuse_name) const
Definition: itype.cpp:161

References _, Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), bio_digestion, itype::can_use(), clamp(), itype::comestible, compute_effective_nutrients(), debugmsg, effect_bloated, effect_tapeworm, flag_NO_BLOAT(), g, stomach_contents::get_calories(), item::get_comestible(), item::get_contained(), item::get_relative_rot(), get_stored_kcal(), get_thirst(), item::has_any_flag(), has_bionic(), Creature::has_effect(), item::has_flag(), has_trait(), healall(), herbivore_blacklist(), stomach_contents::ingest(), item::is_comestible(), item::is_container(), Creature::is_npc(), m_debug, m_good, m_mixed, max_stored_kcal(), mod_healthy_mod(), mod_pain(), mod_stored_kcal(), mod_thirst(), modify_addiction(), modify_fatigue(), modify_health(), modify_morale(), modify_radiation(), modify_stimulation(), mon_player_blob, nutrition_for(), pos(), roll_remainder(), slaked, stomach, trait_EATHEALTH, trait_GOURMAND, trait_HERBIVORE, trait_PROJUNK2, trait_RUMINANT, trait_SAPROPHAGE, trait_SAPROVORE, trait_SLIMESPAWNER, trait_THRESH_PLANT, and item::type.

Referenced by consume_med(), eat(), iuse::ecig(), and try_consume().

◆ consume_item()

bool Character::consume_item ( item target)

Consume given item (food, fuel, medicine, ...).

Returns
true if item should be destroyed (last charge was consumed)

Definition at line 1510 of file consumption.cpp.

1511{
1512 if( target.is_null() ) {
1513 add_msg_if_player( m_info, _( "You do not have that item." ) );
1514 return false;
1515 }
1517 add_msg_if_player( m_info, _( "You can't do that while underwater." ) );
1518 return false;
1519 }
1520
1521 item &comest = get_consumable_from( target );
1522
1523 if( comest.is_null() || target.is_craft() ) {
1524 add_msg_if_player( m_info, _( "You can't eat your %s." ), target.tname() );
1525 if( is_npc() ) {
1526 debugmsg( "%s tried to eat a %s", name, target.tname() );
1527 }
1528 return false;
1529 }
1530 if( is_avatar() && !query_consume_ownership( target, *as_avatar() ) ) {
1531 return false;
1532 }
1533 if( consume_med( comest ) ||
1534 eat( comest ) ||
1535 feed_furnace_with( comest ) ||
1536 fuel_bionic_with( comest ) ) {
1537
1538 if( target.is_container() ) {
1539 target.on_contents_changed();
1540 }
1541
1542 return comest.charges <= 0;
1543 }
1544
1545 return false;
1546}
bool eat(item &food, bool force=false)
Used for eating entered comestible, returns true if comestible is successfully eaten.
bool feed_furnace_with(item &it)
Recharge CBMs whenever possible.
bool fuel_bionic_with(item &it)
item & get_consumable_from(item &it) const
Returns a reference to the item itself (if it's consumable), the first of its contents (if it's consu...
bool consume_med(item &target)
Consume an item as medication.
virtual bool is_avatar() const
Definition: creature.h:95
void on_contents_changed()
Callback when contents of the item are affected in any way other than just processing.
Definition: item.cpp:4558
bool query_consume_ownership(item &target, avatar &you)

References _, Creature::add_msg_if_player(), Creature::as_avatar(), item::charges, consume_med(), debugmsg, eat(), feed_furnace_with(), fuel_bionic_with(), get_consumable_from(), has_trait(), Creature::is_avatar(), item::is_container(), item::is_craft(), Creature::is_npc(), item::is_null(), Creature::is_underwater(), m_info, name, item::on_contents_changed(), query_consume_ownership(), item::tname(), and trait_WATERSLEEP.

Referenced by consume(), and avatar_action::eat().

◆ consume_med()

bool Character::consume_med ( item target)

Consume an item as medication.

Parameters
targetItem consumed. Must be a medication or a container of medication.
Returns
true if item should be destroyed (last charge was consumed)

Definition at line 1602 of file consumption.cpp.

1603{
1604 if( !target.is_medication() ) {
1605 return false;
1606 }
1607
1608 const itype_id tool_type = target.get_comestible()->tool;
1609 const itype *req_tool = &*tool_type;
1610 bool check_tool = true;
1611 if( tool_type == itype_syringe && has_bionic( bio_syringe ) ) {
1612 check_tool = false;
1613 }
1614 if( req_tool->tool ) {
1615 if( check_tool && !(
1616 has_amount( tool_type, 1 ) &&
1617 has_charges( tool_type, req_tool->tool->charges_per_use )
1618 ) ) {
1619 add_msg_if_player( m_info, _( "You need a %s to consume that!" ), req_tool->nname( 1 ) );
1620 return false;
1621 }
1622 use_charges( tool_type, req_tool->tool->charges_per_use );
1623 }
1624
1625 int amount_used = 1;
1626 if( target.type->has_use() ) {
1627 amount_used = target.type->invoke( *this->as_player(), target, pos() );
1628 if( amount_used <= 0 ) {
1629 return false;
1630 }
1631 }
1632
1633 // TODO: Get the target it was used on
1634 // Otherwise injecting someone will give us addictions etc.
1635 if( target.has_flag( "NO_INGEST" ) ) {
1636 const auto &comest = *target.get_comestible();
1637 // Assume that parenteral meds don't spoil, so don't apply rot
1638 modify_health( comest );
1639 modify_stimulation( comest );
1640 modify_fatigue( comest );
1641 modify_radiation( comest );
1642 modify_addiction( comest );
1643 modify_morale( target );
1644 } else {
1645 // Take by mouth
1646 consume_effects( target );
1647 }
1648
1649 mod_moves( -250 );
1650 target.charges -= amount_used;
1651 return target.charges <= 0;
1652}
bool consume_effects(item &food)
Handles the effects of consuming an item.
static const bionic_id bio_syringe("bio_syringe")
static const itype_id itype_syringe("syringe")
cata::value_ptr< islot_tool > tool
Definition: itype.h:817
bool has_use() const
Definition: itype.cpp:141
int invoke(player &p, item &it, const tripoint &pos) const
Definition: itype.cpp:180
std::string nname(unsigned int quantity) const
Definition: itype.cpp:78

References _, Creature::add_msg_if_player(), Creature::as_player(), bio_syringe, item::charges, consume_effects(), item::get_comestible(), visitable< Character >::has_amount(), has_bionic(), has_charges(), item::has_flag(), itype::has_use(), itype::invoke(), item::is_medication(), itype_syringe, m_info, Creature::mod_moves(), modify_addiction(), modify_fatigue(), modify_health(), modify_morale(), modify_radiation(), modify_stimulation(), itype::nname(), pos(), itype::tool, item::type, and use_charges().

Referenced by consume_item().

◆ consume_remote_fuel()

int Character::consume_remote_fuel ( int  amount)

Consume fuel used by remote powered bionic, return amount of request unfulfilled (0 if totally successful).

Definition at line 1454 of file bionics.cpp.

1455{
1456 int unconsumed_amount = amount;
1457 const std::vector<item *> cables = items_with( []( const item & it ) {
1458 return it.active && it.has_flag( flag_CABLE_SPOOL );
1459 } );
1460
1461 map &here = get_map();
1462 for( const item *cable : cables ) {
1463 const std::optional<tripoint> target = cable->get_cable_target( this, pos() );
1464 if( target ) {
1465 const optional_vpart_position vp = here.veh_at( *target );
1466 if( !vp ) {
1467 continue;
1468 }
1469 unconsumed_amount = vp->vehicle().discharge_battery( amount );
1470 }
1471 }
1472
1473 if( unconsumed_amount > 0 ) {
1474 static const item_filter used_ups = [&]( const item & itm ) {
1475 return itm.get_var( "cable" ) == "plugged_in";
1476 };
1477 if( has_charges( itype_UPS_off, unconsumed_amount, used_ups ) ) {
1478 use_charges( itype_UPS_off, unconsumed_amount, used_ups );
1479 unconsumed_amount -= 1;
1480 } else if( has_charges( itype_adv_UPS_off, unconsumed_amount, used_ups ) ) {
1481 use_charges( itype_adv_UPS_off, roll_remainder( unconsumed_amount * 0.6 ), used_ups );
1482 unconsumed_amount -= 1;
1483 }
1484 }
1485
1486 return unconsumed_amount;
1487}
static const itype_id itype_adv_UPS_off("adv_UPS_off")
static const itype_id itype_UPS_off("UPS_off")
std::function< bool(const item &)> item_filter
Definition: game.h:119

References item::active, flag_CABLE_SPOOL(), get_map(), has_charges(), item::has_flag(), visitable< Character >::items_with(), itype_adv_UPS_off, itype_UPS_off, pos(), roll_remainder(), and use_charges().

Referenced by burn_fuel().

◆ cough()

void Character::cough ( bool  harmful = false,
int  loudness = 4 
)

Definition at line 7546 of file character.cpp.

7547{
7549 return;
7550 }
7551
7552 if( harmful ) {
7553 const int stam = get_stamina();
7554 const int malus = get_stamina_max() * 0.05; // 5% max stamina
7555 mod_stamina( -malus );
7556 if( stam < malus && x_in_y( malus - stam, malus ) && one_in( 6 ) ) {
7557 apply_damage( nullptr, bodypart_id( "torso" ), 1 );
7558 }
7559 // Asthmatic characters gain increased risk of an asthma attack from smoke and other dangerous respiratory effects.
7560 if( has_trait( trait_ASTHMA ) ) {
7562 }
7563 }
7564
7565 if( !is_npc() ) {
7566 add_msg( m_bad, _( "You cough heavily." ) );
7567 }
7568 sounds::sound( pos(), loudness, sounds::sound_t::speech, _( "a hacking cough." ), false, "misc",
7569 "cough" );
7570
7571 moves -= 80;
7572
7573 add_effect( effect_recently_coughed, 5_minutes );
7574}
static const efftype_id effect_cough_suppress("cough_suppress")
static const efftype_id effect_recently_coughed("recently_coughed")
static const efftype_id effect_cough_aggravated_asthma("cough_aggravated_asthma")
static const trait_id trait_ASTHMA("ASTHMA")

References _, Creature::add_effect(), add_msg(), apply_damage(), effect_cough_aggravated_asthma, effect_cough_suppress, effect_recently_coughed, get_stamina(), get_stamina_max(), Creature::has_effect(), has_trait(), Creature::is_npc(), m_bad, mod_stamina(), Creature::moves, one_in(), pos(), sounds::sound(), sounds::speech, trait_ASTHMA, and x_in_y().

Referenced by eff_fun_fungus(), and process_one_effect().

◆ covered_with_flag()

bool Character::covered_with_flag ( const std::string &  flag,
const body_part_set parts 
) const

Definition at line 8974 of file character.cpp.

8975{
8976 if( parts.none() ) {
8977 return true;
8978 }
8979
8980 body_part_set to_cover( parts );
8981
8982 for( const auto &elem : worn ) {
8983 if( !elem.has_flag( flag ) ) {
8984 continue;
8985 }
8986
8987 to_cover &= ~elem.get_covered_body_parts();
8988
8989 if( to_cover.none() ) {
8990 return true; // Allows early exit.
8991 }
8992 }
8993
8994 return to_cover.none();
8995}
bool none() const
Definition: bodypart.h:265

References body_part_set::none(), and worn.

Referenced by is_waterproof().

◆ crafting_inventory() [1/2]

const inventory & Character::crafting_inventory ( bool  clear_path)

Definition at line 556 of file crafting.cpp.

557{
558 return crafting_inventory( tripoint_zero, PICKUP_RANGE, clear_path );
559}
const inventory & crafting_inventory(bool clear_path)
Definition: crafting.cpp:556

References crafting_inventory(), PICKUP_RANGE, and tripoint_zero.

Referenced by iexamine::autodoc(), autodoc_internal(), game::butcher(), activity_handlers::butcher_finish(), butcher_submenu(), can_butcher_at(), player::can_continue_craft(), can_do_activity_there(), player::can_make(), player::can_start_craft(), complete_craft(), veh_interact::complete_vehicle(), consider_butchery(), construction_color(), activity_handlers::cracking_do_turn(), iuse::craft(), crafting_inventory(), iexamine::cvdmachine(), iuse::dig(), game_menus::inv::disassemble(), item::final_info(), wash_activity_actor::finish(), bionic_install_preset::get_failure_chance(), repair_item_actor::handle_components(), has_enough_anesth(), list_available_constructions(), avatar_funcs::mend_item(), activity_handlers::mend_item_finish(), mill_load_food(), iuse::modify_grid_connections(), modify_morale(), veh_utils::most_repairable_part(), iexamine::nanofab(), iexamine::pit(), prompt_disassemble_in_seq(), examine_item_menu::rate_action_disassemble(), veh_utils::repair_part(), iexamine::safe(), deduped_requirement_data::select_alternative(), select_crafting_recipe(), iexamine::sign(), smoker_load_food(), iexamine::tree_maple(), disassemble_activity_actor::try_start_single(), sew_advanced_actor::use(), and wash_items().

◆ crafting_inventory() [2/2]

const inventory & Character::crafting_inventory ( const tripoint src_pos = tripoint_zero,
int  radius = PICKUP_RANGE,
bool  clear_path = true 
)

Definition at line 561 of file crafting.cpp.

563{
564 tripoint inv_pos = src_pos;
565 if( src_pos == tripoint_zero ) {
566 inv_pos = pos();
567 }
568 if( cached_moves == moves
570 && cached_position == inv_pos ) {
572 }
573 cached_crafting_inventory.form_from_map( inv_pos, radius, this, false, clear_path );
577 for( const bionic &bio : *my_bionics ) {
578 const bionic_data &bio_data = bio.info();
579 if( ( !bio_data.activated || bio.powered ) &&
580 !bio_data.fake_item.is_empty() ) {
581 cached_crafting_inventory += item( bio.info().fake_item,
583 }
584 }
585 if( has_trait( trait_BURROW ) ) {
588 }
589
592 cached_position = inv_pos;
593 // cache the qualities of the items in cached_crafting_inventory
596}
tripoint cached_position
Definition: character.h:2276
int cached_moves
Definition: character.h:2275
inventory cached_crafting_inventory
Definition: character.h:2277
void form_from_map(const tripoint &origin, int range, const Character *pl=nullptr, bool assign_invlet=true, bool clear_path=true)
Definition: inventory.cpp:473
void update_quality_cache()
Definition: inventory.cpp:1117
static const trait_id trait_BURROW("BURROW")
bool activated
Is true if a bionic is an active instead of a passive bionic.
Definition: bionics.h:53

References bionic_data::activated, cached_crafting_inventory, cached_moves, cached_position, cached_time, bionic_data::fake_item, inventory::form_from_map(), get_power_level(), has_trait(), inv, string_id< T >::is_empty(), Creature::moves, my_bionics, pos(), primary_weapon(), units::to_kilojoule(), trait_BURROW, tripoint_zero, calendar::turn, inventory::update_quality_cache(), and worn.

◆ crit_chance()

double Character::crit_chance ( float  roll_hit,
float  target_dodge,
const item weap 
) const

Returns the chance to critical given a hit roll and target's dodge roll.

Unarmed increases critical chance with UNARMED_WEAPON Dexterity increases chance for critical hits Perception increases chance for critical hits Bashing increases critical chance with bashing weapons Cutting increases critical chance with cutting weapons Stabbing increases critical chance with piercing weapons Unarmed increases critical chance with unarmed weapons Melee slightly increases critical chance with any item

Definition at line 796 of file melee.cpp.

797{
798 // Weapon to-hit roll
799 double weapon_crit_chance = 0.5;
800 if( weap.is_unarmed_weapon() ) {
801 // Unarmed attack: 1/2 of unarmed skill is to-hit
802 /** @EFFECT_UNARMED increases critical chance with UNARMED_WEAPON */
803 weapon_crit_chance = 0.5 + 0.05 * get_skill_level( skill_unarmed );
804 }
805
806 if( weap.type->m_to_hit > 0 ) {
807 weapon_crit_chance = std::max( weapon_crit_chance, 0.5 + 0.1 * weap.type->m_to_hit );
808 } else if( weap.type->m_to_hit < 0 ) {
809 weapon_crit_chance += 0.1 * weap.type->m_to_hit;
810 }
811 weapon_crit_chance = limit_probability( weapon_crit_chance );
812
813 // Dexterity and perception
814 /** @EFFECT_DEX increases chance for critical hits */
815
816 /** @EFFECT_PER increases chance for critical hits */
817 const double stat_crit_chance = limit_probability( 0.25 + 0.01 * dex_cur + ( 0.02 * per_cur ) );
818
819 /** @EFFECT_BASHING increases critical chance with bashing weapons */
820 /** @EFFECT_CUTTING increases critical chance with cutting weapons */
821 /** @EFFECT_STABBING increases critical chance with piercing weapons */
822 /** @EFFECT_UNARMED increases critical chance with unarmed weapons */
823 int sk = get_skill_level( weap.melee_skill() );
824 if( has_active_bionic( bio_cqb ) ) {
825 sk = std::max( sk, BIO_CQB_LEVEL );
826 }
827
828 /** @EFFECT_MELEE slightly increases critical chance with any item */
829 sk += get_skill_level( skill_melee ) / 2.5;
830
831 const double skill_crit_chance = limit_probability( 0.25 + sk * 0.025 );
832
833 // Examples (survivor stats/chances of each critical):
834 // Fresh (skill-less) 8/8/8/8, unarmed:
835 // 50%, 49%, 25%; ~1/16 guaranteed critical + ~1/8 if roll>dodge*1.5
836 // Expert (skills 10) 10/10/10/10, unarmed:
837 // 100%, 55%, 60%; ~1/3 guaranteed critical + ~4/10 if roll>dodge*1.5
838 // Godlike with combat CBM 20/20/20/20, pipe (+1 accuracy):
839 // 60%, 100%, 42%; ~1/4 guaranteed critical + ~3/8 if roll>dodge*1.5
840
841 // Note: the formulas below are only valid if none of the 3 critical chance values go above 1.0
842 // It is therefore important to limit them to between 0.0 and 1.0
843
844 // Chance to get all 3 criticals (a guaranteed critical regardless of hit/dodge)
845 const double chance_triple = weapon_crit_chance * stat_crit_chance * skill_crit_chance;
846 // Only check double critical (one that requires hit/dodge comparison) if we have good
847 // hit vs dodge
848 if( roll_hit > target_dodge * 3 / 2 ) {
849 const double chance_double = 0.5 * (
850 weapon_crit_chance * stat_crit_chance +
851 stat_crit_chance * skill_crit_chance +
852 weapon_crit_chance * skill_crit_chance -
853 ( 3 * chance_triple ) );
854 // Because chance_double already removed the triples with -( 3 * chance_triple ),
855 // chance_triple and chance_double are mutually exclusive probabilities and can just
856 // be added together.
858 melee::melee_stats.double_crit_chance += chance_double + chance_triple;
859 return chance_triple + chance_double;
860 }
862 melee::melee_stats.crit_chance += chance_triple;
863 return chance_triple;
864}
bool is_unarmed_weapon() const
Definition: item.cpp:741
skill_id melee_skill() const
The most relevant skill used with this melee weapon.
Definition: item.cpp:7220
double limit_probability(double unbounded_probability)
Limits a probability to be between 0.0 and 1.0.
Definition: melee.cpp:791
melee_statistic_data melee_stats
Definition: melee.cpp:2520
int m_to_hit
Definition: itype.h:966
double crit_chance
Definition: melee.h:15
int double_crit_count
Definition: melee.h:11
double double_crit_chance
Definition: melee.h:14

References bio_cqb, BIO_CQB_LEVEL, melee_statistic_data::crit_chance, melee_statistic_data::crit_count, dex_cur, melee_statistic_data::double_crit_chance, melee_statistic_data::double_crit_count, get_skill_level(), has_active_bionic(), item::is_unarmed_weapon(), limit_probability(), itype::m_to_hit, item::melee_skill(), melee::melee_stats, per_cur, skill_melee, skill_unarmed, and item::type.

Referenced by item::combat_info(), item::effective_dps(), and scored_crit().

◆ crossed_threshold()

bool Character::crossed_threshold ( ) const

Returns true if the player has crossed a mutation threshold Player can only cross one mutation threshold.

Definition at line 8718 of file character.cpp.

8719{
8720 for( const trait_id &mut : get_mutations() ) {
8721 if( mut->threshold ) {
8722 return true;
8723 }
8724 }
8725 return false;
8726}

References get_mutations(), and mutation_branch::threshold.

Referenced by character_display::disp_info(), draw_tip(), hardcoded_effects(), marloss_common(), modify_morale(), conditional_t< T >::set_has_trait_flag(), and test_crossing_threshold().

◆ deactivate_bionic()

bool Character::deactivate_bionic ( bionic bio,
bool  eff_only = false 
)

Handles bionic deactivation effects of the entered bionic, returns if anything deactivated.

Definition at line 1108 of file bionics.cpp.

1109{
1110 if( bio.incapacitated_time > 0_turns ) {
1111 add_msg_if_player( m_info, _( "Your %s is shorting out and can't be deactivated." ),
1112 bio.info().name );
1113 return false;
1114 }
1115
1116 if( bio.info().is_remote_fueled ) {
1118 }
1119
1120 // Just do the effect, no stat changing or messages
1121 if( !eff_only ) {
1122 if( !bio.powered ) {
1123 // It's already off!
1124 return false;
1125 }
1126 if( !bio.info().has_flag( flag_BIONIC_TOGGLED ) ) {
1127 // It's a fire-and-forget bionic, we can't turn it off but have to wait for
1128 //it to run out of charge
1129 add_msg_if_player( m_info, _( "You can't deactivate your %s manually!" ),
1130 bio.info().name );
1131 return false;
1132 }
1133 if( get_power_level() < bio.info().power_deactivate ) {
1134 add_msg_if_player( m_info, _( "You don't have the power to deactivate your %s." ),
1135 bio.info().name );
1136 return false;
1137 }
1138
1139 //We can actually deactivate now, do deactivation-y things
1141 bio.powered = false;
1142 add_msg_if_player( m_neutral, _( "You deactivate your %s." ), bio.info().name );
1143 }
1144
1145 // Deactivation effects go here
1146 if( bio.info().has_flag( flag_BIONIC_WEAPON ) ) {
1147 if( primary_weapon().typeId() == bio.info().fake_item ) {
1148 add_msg_if_player( _( "You withdraw your %s." ), primary_weapon().tname() );
1149 if( g->u.sees( pos() ) ) {
1150 add_msg_if_npc( m_info, _( "<npcname> withdraws their %s." ), primary_weapon().tname() );
1151 }
1152 bio.ammo_loaded =
1153 primary_weapon().ammo_data() != nullptr ? primary_weapon().ammo_data()->get_id() :
1155 bio.ammo_count = static_cast<unsigned int>( primary_weapon().ammo_remaining() );
1158 }
1159 } else if( bio.id == bio_cqb ) {
1160 martial_arts_data->selected_style_check();
1161 } else if( bio.id == bio_remote ) {
1162 if( g->remoteveh() != nullptr && !has_active_item( itype_remotevehcontrol ) ) {
1163 g->setremoteveh( nullptr );
1164 } else if( !get_value( "remote_controlling" ).empty() &&
1166 set_value( "remote_controlling", "" );
1167 }
1168 } else if( bio.id == bio_tools ) {
1170 } else if( bio.id == bio_ads ) {
1172 bio.energy_stored = 0_kJ;
1173 }
1174
1175 // Recalculate stats (strength, mods from pain etc.) that could have been affected
1177 reset();
1178 if( !bio.id->enchantments.empty() ) {
1180 }
1181
1182 // Also reset crafting inventory cache if this bionic spawned a fake item
1183 if( !bio.info().fake_item.is_empty() ) {
1185 }
1186
1187 // Compatibility with old saves without the toolset hammerspace
1188 if( !eff_only && bio.id == bio_tools && !has_bionic( bionic_TOOLS_EXTEND ) ) {
1189 // E X T E N D T O O L S
1191 }
1192
1193 return true;
1194}
static const bionic_id bio_ads("bio_ads")
static const itype_id itype_remotevehcontrol("remotevehcontrol")
static const bionic_id bionic_TOOLS_EXTEND("bio_tools_extend")
static const itype_id itype_radiocontrol("radiocontrol")
bool has_active_item(const itype_id &id) const
Whether the player carries an active item of the given item type.
Definition: character.cpp:2509
void reset_remote_fuel()
Definition: bionics.cpp:1489
virtual void add_msg_if_npc(const std::string &) const
Definition: creature.h:647
const itype * ammo_data() const
Specific ammo data, returns nullptr if item is neither ammo nor loaded with any.
Definition: item.cpp:7550
static const string_id< itype > & NULL_ID()
Returns a null id whose string_id<T>::is_null() must always return true.
units::energy power_deactivate
Power cost on deactivation.
Definition: bionics.h:39

References _, add_bionic(), Creature::add_msg_if_npc(), Creature::add_msg_if_player(), bionic::ammo_count, item::ammo_data(), bionic::ammo_loaded, item::ammo_remaining(), bio_ads, bio_cqb, bio_remote, bio_tools, bionic_TOOLS_EXTEND, bionic_data::enchantments, bionic::energy_stored, bionic_data::fake_item, flag_BIONIC_TOGGLED, flag_BIONIC_WEAPON, g, itype::get_id(), get_power_level(), Creature::get_value(), has_active_item(), has_bionic(), bionic_data::has_flag(), bionic::id, bionic::incapacitated_time, bionic::info(), invalidate_crafting_inventory(), string_id< T >::is_empty(), bionic_data::is_remote_fueled, itype_radiocontrol, itype_remotevehcontrol, m_info, m_neutral, martial_arts_data, mod_power_level(), bionic_data::name, string_id< itype >::NULL_ID(), pos(), bionic_data::power_deactivate, bionic::powered, primary_weapon(), recalculate_enchantment_cache(), reset(), reset_encumbrance(), reset_remote_fuel(), set_primary_weapon(), and Creature::set_value().

Referenced by absorb_hit(), burn_fuel(), npc::deactivate_bionic_by_id(), deactivate_weapon_cbm(), process_bionic(), show_bionics_ui(), and uninstall_bionic().

◆ deactivate_mutation()

void Character::deactivate_mutation ( const trait_id mut)

Definition at line 595 of file mutation.cpp.

596{
597 my_mutations[mut].powered = false;
598
599 // Handle stat changes from deactivation
600 apply_mods( mut, false );
602 const mutation_branch &mdata = mut.obj();
603 if( mdata.transform ) {
604 const cata::value_ptr<mut_transform> trans = mdata.transform;
605 mod_moves( -trans->moves );
606 switch_mutations( mut, trans->target, trans->active );
607 }
608
609 if( !mut->enchantments.empty() ) {
611 }
612}
void apply_mods(const trait_id &mut, bool add_remove)
Applies stat mods to character.
Definition: mutation.cpp:204
std::vector< enchantment_id > enchantments
mutation enchantments
Definition: mutation.h:236

References apply_mods(), mutation_branch::enchantments, Creature::mod_moves(), my_mutations, string_id< T >::obj(), recalc_sight_limits(), recalculate_enchantment_cache(), switch_mutations(), and mutation_branch::transform.

Referenced by show_mutations_ui(), and detail::show_mutations_ui_internal().

◆ deal_damage()

dealt_damage_instance Character::deal_damage ( Creature source,
bodypart_id  bp,
const damage_instance d 
)
overridevirtual

Calls Creature::deal_damage and handles damaged effects (waking up, etc.)

Dexterity increases chance to avoid being grabbed

Reimplemented from Creature.

Definition at line 8464 of file character.cpp.

8466{
8467 if( has_trait( trait_DEBUG_NODMG ) ) {
8468 return dealt_damage_instance();
8469 }
8470
8471 const body_part bp_token = bp->token;
8472 if( bp_token == num_bp ) {
8473 debugmsg( "Wacky bodypart hit!" );
8474 return dealt_damage_instance();
8475 }
8476
8477 //damage applied here
8478 dealt_damage_instance dealt_dams = Creature::deal_damage( source, bp, d );
8479 //block reduction should be by applied this point
8480 int dam = dealt_dams.total_damage();
8481
8482 // TODO: Pre or post blit hit tile onto "this"'s location here
8483 if( dam > 0 && g->u.sees( pos() ) ) {
8484 g->draw_hit_player( *this, dam );
8485
8486 if( is_player() && source ) {
8487 //monster hits player melee
8488 SCT.add( point( posx(), posy() ),
8489 direction_from( point_zero, point( posx() - source->posx(), posy() - source->posy() ) ),
8490 get_hp_bar( dam, get_hp_max( bp ) ).first, m_bad, body_part_name( bp ), m_neutral );
8491 }
8492 }
8493
8494 // handle snake artifacts
8495 if( has_artifact_with( AEP_SNAKES ) && dam >= 6 ) {
8496 const int snakes = dam / 6;
8497 int spawned = 0;
8498 for( int i = 0; i < snakes; i++ ) {
8499 if( monster *const snake = g->place_critter_around( mon_shadow_snake, pos(), 1 ) ) {
8500 snake->friendly = -1;
8501 spawned++;
8502 }
8503 }
8504 if( spawned == 1 ) {
8505 add_msg( m_warning, _( "A snake sprouts from your body!" ) );
8506 } else if( spawned >= 2 ) {
8507 add_msg( m_warning, _( "Some snakes sprout from your body!" ) );
8508 }
8509 }
8510
8511 // And slimespawners too
8512 if( ( has_trait( trait_SLIMESPAWNER ) ) && ( dam >= 10 ) && one_in( 20 - dam ) ) {
8513 if( monster *const slime = g->place_critter_around( mon_player_blob, pos(), 1 ) ) {
8514 slime->friendly = -1;
8515 add_msg_if_player( m_warning, _( "Slime is torn from you, and moves on its own!" ) );
8516 }
8517 }
8518
8519 //Acid blood effects.
8520 bool u_see = g->u.sees( *this );
8521 int cut_dam = dealt_dams.type_damage( DT_CUT );
8522 if( source && has_trait( trait_ACIDBLOOD ) && !one_in( 3 ) &&
8523 ( dam >= 4 || cut_dam > 0 ) && ( rl_dist( g->u.pos(), source->pos() ) <= 1 ) ) {
8524 if( is_player() ) {
8525 add_msg( m_good, _( "Your acidic blood splashes %s in mid-attack!" ),
8526 source->disp_name() );
8527 } else if( u_see ) {
8528 add_msg( _( "%1$s's acidic blood splashes on %2$s in mid-attack!" ),
8529 disp_name(), source->disp_name() );
8530 }
8531 damage_instance acidblood_damage;
8532 acidblood_damage.add_damage( DT_ACID, rng( 4, 16 ) );
8533 if( !one_in( 4 ) ) {
8534 source->deal_damage( this, bodypart_id( "arm_l" ), acidblood_damage );
8535 source->deal_damage( this, bodypart_id( "arm_r" ), acidblood_damage );
8536 } else {
8537 source->deal_damage( this, bodypart_id( "torso" ), acidblood_damage );
8538 source->deal_damage( this, bodypart_id( "head" ), acidblood_damage );
8539 }
8540 }
8541
8542 int recoil_mul = 100;
8543
8544 if( bp == bodypart_id( "eyes" ) ) {
8545 if( dam > 5 || cut_dam > 0 ) {
8546 const time_duration minblind = std::max( 1_turns, 1_turns * ( dam + cut_dam ) / 10 );
8547 const time_duration maxblind = std::min( 5_turns, 1_turns * ( dam + cut_dam ) / 4 );
8548 add_effect( effect_blind, rng( minblind, maxblind ) );
8549 }
8550 } else if( bp == bodypart_id( "hand_l" ) || bp == bodypart_id( "arm_l" ) ||
8551 bp == bodypart_id( "hand_r" ) || bp == bodypart_id( "arm_r" ) ) {
8552 recoil_mul = 200;
8553 } else if( bp == bodypart_id( "num_bp" ) ) {
8554 debugmsg( "Wacky body part hit!" );
8555 }
8556
8557
8558
8559 // TODO: Scale with damage in a way that makes sense for power armors, plate armor and naked skin.
8560 const item &weapon = primary_weapon();
8561 recoil += recoil_mul * weapon.volume() / 250_ml;
8562 recoil = std::min( MAX_RECOIL, recoil );
8563 //looks like this should be based off of dealt damages, not d as d has no damage reduction applied.
8564 // Skip all this if the damage isn't from a creature. e.g. an explosion.
8565 if( source != nullptr ) {
8566 if( source->has_flag( MF_GRABS ) && !source->is_hallucination() &&
8567 !source->has_effect( effect_grabbing ) ) {
8568 /** @EFFECT_DEX increases chance to avoid being grabbed */
8569
8570 if( has_grab_break_tec() && ( rng( 0, get_dex() ) > rng( 0, 10 ) ) ) {
8571 if( has_effect( effect_grabbed ) ) {
8572 add_msg_if_player( m_warning, _( "The %s tries to grab you as well, but you bat it away!" ),
8573 source->disp_name() );
8574 } else {
8575 add_msg_player_or_npc( m_info, _( "The %s tries to grab you, but you break its grab!" ),
8576 _( "The %s tries to grab <npcname>, but they break its grab!" ),
8577 source->disp_name() );
8578 }
8579 } else {
8580 int prev_effect = get_effect_int( effect_grabbed );
8581 add_effect( effect_grabbed, 2_turns, bp_torso, prev_effect + 2 );
8582 source->add_effect( effect_grabbing, 2_turns );
8583 add_msg_player_or_npc( m_bad, _( "You are grabbed by %s!" ), _( "<npcname> is grabbed by %s!" ),
8584 source->disp_name() );
8585 }
8586 }
8587 }
8588
8589 if( get_option<bool>( "FILTHY_WOUNDS" ) ) {
8590 int sum_cover = 0;
8591 for( const item &i : worn ) {
8592 if( i.covers( bp->token ) && i.is_filthy() ) {
8593 sum_cover += i.get_coverage();
8594 }
8595 }
8596
8597 // Chance of infection is damage (with cut and stab x4) * sum of coverage on affected body part, in percent.
8598 // i.e. if the body part has a sum of 100 coverage from filthy clothing,
8599 // each point of damage has a 1% change of causing infection.
8600 if( sum_cover > 0 ) {
8601 const int cut_type_dam = dealt_dams.type_damage( DT_CUT ) + dealt_dams.type_damage( DT_STAB );
8602 const int combined_dam = dealt_dams.type_damage( DT_BASH ) + ( cut_type_dam * 4 );
8603 const int infection_chance = ( combined_dam * sum_cover ) / 100;
8604 if( x_in_y( infection_chance, 100 ) ) {
8605 if( has_effect( effect_bite, bp->token ) ) {
8606 add_effect( effect_bite, 40_minutes, bp->token );
8607 } else if( has_effect( effect_infected, bp->token ) ) {
8608 add_effect( effect_infected, 25_minutes, bp->token );
8609 } else {
8610 add_effect( effect_bite, 1_turns, bp->token );
8611 }
8612 add_msg_if_player( _( "Filth from your clothing has implanted deep in the wound." ) );
8613 }
8614 }
8615 }
8616
8617 on_hurt( source );
8618 return dealt_dams;
8619}
static const efftype_id effect_blind("blind")
static const trait_id trait_SLIMESPAWNER("SLIMESPAWNER")
static const mtype_id mon_player_blob("mon_player_blob")
static const efftype_id effect_grabbing("grabbing")
static const mtype_id mon_shadow_snake("mon_shadow_snake")
static const efftype_id effect_grabbed("grabbed")
double recoil
Definition: character.h:571
virtual int posy() const =0
virtual std::string disp_name(bool possessive=false, bool capitalize_first=false) const =0
virtual const tripoint & pos() const =0
virtual dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &dam)
Deals the damage via an attack.
Definition: creature.cpp:901
virtual int get_hp_max() const
Definition: creature.cpp:1716
virtual int posx() const =0
units::volume volume(bool integral=false) const
Total volume of an item accounting for all contained/integrated items NOTE: Result is rounded up to n...
Definition: item.cpp:5129
direction direction_from(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:540
@ AEP_SNAKES
Definition: enums.h:109
constexpr double MAX_RECOIL
@ MF_GRABS
Definition: mtype.h:76
bool snake(const tripoint &p, Creature *c, item *i)
Definition: trapfunc.cpp:1428
static constexpr point point_zero
Definition: point.h:260
void add_damage(damage_type dt, float amt, float arpen=0.0f, float arpen_mult=1.0f, float dmg_mult=1.0f)
Adds damage to the instance.
Definition: damage.cpp:41
int type_damage(damage_type dt) const
Definition: damage.cpp:172
int total_damage() const
Definition: damage.cpp:180

References _, scrollingcombattext::add(), damage_instance::add_damage(), Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), AEP_SNAKES, body_part_name(), bp_torso, Creature::deal_damage(), debugmsg, direction_from(), Creature::disp_name(), disp_name(), DT_ACID, DT_BASH, DT_CUT, DT_STAB, effect_bite, effect_blind, effect_grabbed, effect_grabbing, effect_infected, g, get_dex(), Creature::get_effect_int(), get_hp_bar(), Creature::get_hp_max(), has_artifact_with(), Creature::has_effect(), Creature::has_flag(), has_grab_break_tec(), has_trait(), Creature::is_hallucination(), Creature::is_player(), m_bad, m_good, m_info, m_neutral, m_warning, MAX_RECOIL, MF_GRABS, mon_player_blob, mon_shadow_snake, num_bp, on_hurt(), one_in(), point_zero, Creature::pos(), pos(), Creature::posx(), posx(), Creature::posy(), posy(), primary_weapon(), recoil, rl_dist(), rng(), SCT, trapfunc::snake(), dealt_damage_instance::total_damage(), trait_ACIDBLOOD, trait_DEBUG_NODMG, trait_SLIMESPAWNER, dealt_damage_instance::type_damage(), item::volume(), worn, and x_in_y().

Referenced by mattack::bio_op_impale(), mattack::bio_op_takedown(), explosion_handler::ExplosionProcess::blast_tile(), map::burn_body_part(), map::crush(), trapfunc::dissector(), map::drop_furniture(), eff_fun_onfire(), trapfunc::goo(), hitall(), impact(), knock_back_to(), game::knockback(), trapfunc::lava(), explosion_handler::legacy_blast(), melee_special_effects(), petfood(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), game::place_player(), map::player_in_field(), smash(), trapfunc::snare_heavy(), and mattack::thrown_by_judo().

◆ defer_move()

bool Character::defer_move ( const tripoint next)

Definition at line 10567 of file character.cpp.

10568{
10569 // next must be adjacent to current pos
10570 if( square_dist( next, pos() ) != 1 ) {
10571 return false;
10572 }
10573 // next must be adjacent to subsequent move in any preexisting automove route
10574 if( has_destination() && square_dist( auto_move_route.front(), next ) != 1 ) {
10575 return false;
10576 }
10577 auto_move_route.insert( auto_move_route.begin(), next );
10579 return true;
10580}
bool has_destination() const
int square_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:505

References auto_move_route, has_destination(), next_expected_position, pos(), and square_dist().

Referenced by avatar_action::move().

◆ did_hit()

void Character::did_hit ( Creature target)

Handles special effects when the Character hits a Creature.

Definition at line 8291 of file character.cpp.

8292{
8293 enchantment_cache->cast_hit_you( *this, target );
8294}

References enchantment_cache.

Referenced by melee_attack().

◆ die()

void Character::die ( Creature killer)
overridevirtual

Empty function.

Should always be overwritten by the appropriate player/NPC/monster version.

Implements Creature.

Reimplemented in npc.

Definition at line 3549 of file character.cpp.

3550{
3551 g->set_critter_died();
3552 set_killer( nkiller );
3554 if( has_effect( effect_lightsnare ) ) {
3557 }
3558 if( has_effect( effect_heavysnare ) ) {
3561 }
3562 if( has_effect( effect_beartrap ) ) {
3564 }
3566}
static const itype_id itype_string_36("string_36")
static const efftype_id effect_lightsnare("lightsnare")
static const itype_id itype_snare_trigger("snare_trigger")
static const itype_id itype_beartrap("beartrap")
static const efftype_id effect_beartrap("beartrap")
static const efftype_id effect_heavysnare("heavysnare")
static const itype_id itype_rope_6("rope_6")
void set_time_died(const time_point &time)
set the turn the turn the character died if not already done
Definition: character.h:1479
static void on_creature_death(Creature &poor_dead_dude)
various callbacks from events that may affect all missions
Definition: mission.cpp:132

References inventory::add_item(), effect_beartrap, effect_heavysnare, effect_lightsnare, g, Creature::has_effect(), inv, itype_beartrap, itype_rope_6, itype_snare_trigger, itype_string_36, mission::on_creature_death(), Creature::set_killer(), set_time_died(), calendar::start_of_cataclysm, and calendar::turn.

Referenced by debug_menu::debug(), and npc::die().

◆ dismount()

void Character::dismount ( )

Definition at line 1186 of file character.cpp.

1187{
1188 if( !is_mounted() ) {
1189 add_msg( m_debug, "dismount called when not riding" );
1190 return;
1191 }
1192 if( const std::optional<tripoint> pnt = choose_adjacent( _( "Dismount where?" ) ) ) {
1193 if( !g->is_empty( *pnt ) ) {
1194 add_msg( m_warning, _( "You cannot dismount there!" ) );
1195 return;
1196 }
1198 monster *critter = mounted_creature.get();
1199 critter->mounted_player_id = character_id();
1200 item &weapon = primary_weapon();
1201 if( critter->has_flag( MF_RIDEABLE_MECH ) && !critter->type->mech_weapon.is_empty() &&
1202 weapon.typeId() == critter->type->mech_weapon ) {
1203 remove_item( weapon );
1204 }
1205 if( is_avatar() && g->u.get_grab_type() != OBJECT_NONE ) {
1206 add_msg( m_warning, _( "You let go of the grabbed object." ) );
1207 g->u.grab( OBJECT_NONE );
1208 }
1209 critter->remove_effect( effect_ridden );
1210 critter->add_effect( effect_ai_waiting, 5_turns );
1211 mounted_creature = nullptr;
1212 critter->mounted_player = nullptr;
1213 setpos( *pnt );
1214 mod_moves( -100 );
1216 }
1217}
static const efftype_id effect_ai_waiting("ai_waiting")
static const efftype_id effect_riding("riding")
static const efftype_id effect_ridden("ridden")
void setpos(const tripoint &p) override
Definition: character.h:815
virtual void set_movement_mode(character_movemode mode)=0
void add_effect(const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false) override
Performs any monster-specific modifications to the arguments before passing to Creature::add_effect()...
Definition: monster.cpp:1856
Character * mounted_player
Definition: monster.h:458
character_id mounted_player_id
Definition: monster.h:459
item remove_item(item &it)
Removes and returns the item which must be contained by this instance.
Definition: visitable.cpp:564
@ OBJECT_NONE
Definition: enums.h:187

References _, monster::add_effect(), add_msg(), character_id, choose_adjacent(), CMM_WALK, effect_ai_waiting, effect_ridden, effect_riding, g, monster::has_flag(), Creature::is_avatar(), string_id< T >::is_empty(), is_mounted(), m_debug, m_warning, mtype::mech_weapon, MF_RIDEABLE_MECH, Creature::mod_moves(), mounted_creature, monster::mounted_player, monster::mounted_player_id, OBJECT_NONE, primary_weapon(), Creature::remove_effect(), visitable< Character >::remove_item(), set_movement_mode(), setpos(), monster::type, and item::typeId().

Referenced by game::handle_action().

◆ disp_name()

std::string Character::disp_name ( bool  possessive = false,
bool  capitalize_first = false 
) const
overridevirtual

Returns either "you" or the player's name.

capitalize_first assumes that the character's name is already upper case and uses it only for possessive "your" and "you"

Implements Creature.

Definition at line 580 of file character.cpp.

581{
582 if( !possessive ) {
583 if( is_player() ) {
584 return capitalize_first ? _( "You" ) : _( "you" );
585 }
586 return name;
587 } else {
588 if( is_player() ) {
589 return capitalize_first ? _( "Your" ) : _( "your" );
590 }
591 return string_format( _( "%s's" ), name );
592 }
593}

References _, Creature::is_player(), name, and string_format().

Referenced by activate_bionic(), activity_on_turn_move_loot(), add_addiction(), iuse::artifact(), talk_function::assign_camp(), iexamine::autodoc(), best_installer(), bionics_install_failure(), activity_handlers::build_do_turn(), can_uninstall_bionic(), npc::character_danger(), game::chat(), check_and_recover_morale(), check_outbounds_activity(), complete_construction(), deal_damage(), faction_manager::display(), npc::do_npc_read(), npc::do_player_activity(), avatar::do_read(), npc::execute_action(), fetch_activity(), npc::finish_read(), talk_function::goto_location(), npc::handle_sound(), npc::heal_player(), npc::heal_self(), install_bionics(), game::list_missions(), npc::method_of_attack(), talk_function::morale_chat(), talk_function::morale_chat_activity(), npc::mutiny(), npc::npc_dismount(), game::npc_menu(), mattack::nurse_operate(), monster::nursebot_operate(), on_hit(), npc::on_load(), npc::pretend_fire(), npc::pretend_heal(), monster::print_info(), npc::reach_omt_destination(), avatar::read(), game_menus::inv::read(), requirements_map(), talk_effect_fun_t::set_consume_item(), npc::set_fac(), npc::set_known_to_u(), talk_function::start_camp(), character_funcs::try_uncanny_dodge(), uninstall_bionic(), trading_window::update_win(), musical_instrument_actor::use(), heal_actor::use_healing_item(), npc::use_painkiller(), and npc::wield_better_weapon().

◆ dispose_item()

bool Character::dispose_item ( item_location &&  obj,
const std::string &  prompt = std::string() 
)
virtual

Drop, wear, stash or otherwise try to dispose of an item consuming appropriate moves.

Parameters
objitem to dispose of
promptoptional message to display in any menu
Returns
whether the item was successfully disposed of

Reimplemented in npc.

Definition at line 7263 of file character.cpp.

7264{
7265 uilist menu;
7266 menu.text = prompt.empty() ? string_format( _( "Dispose of %s" ), obj->tname() ) : prompt;
7267
7268 using dispose_option = struct {
7269 std::string prompt;
7270 bool enabled;
7271 char invlet;
7272 int moves;
7273 std::function<bool()> action;
7274 };
7275
7276 std::vector<dispose_option> opts;
7277
7278 const bool bucket = obj->is_bucket_nonempty();
7279
7280 opts.emplace_back( dispose_option{
7281 bucket ? _( "Spill contents and store in inventory" ) : _( "Store in inventory" ),
7282 volume_carried() + obj->volume() <= volume_capacity(), '1',
7283 item_handling_cost( *obj ),
7284 [this, bucket, &obj] {
7285 if( bucket && !obj->spill_contents( *this ) )
7286 {
7287 return false;
7288 }
7289
7290 moves -= item_handling_cost( *obj );
7291 inv.add_item_keep_invlet( *obj );
7292 inv.unsort();
7293 obj.remove_item();
7294 return true;
7295 }
7296 } );
7297
7298 opts.emplace_back( dispose_option{
7299 _( "Drop item" ), true, '2', 0, [this, &obj] {
7301 obj.remove_item();
7302 return true;
7303 }
7304 } );
7305
7306 opts.emplace_back( dispose_option{
7307 bucket ? _( "Spill contents and wear item" ) : _( "Wear item" ),
7308 can_wear( *obj ).success(), '3', item_wear_cost( *obj ),
7309 [this, bucket, &obj] {
7310 if( bucket && !obj->spill_contents( *this ) )
7311 {
7312 return false;
7313 }
7314
7315 item it = *obj;
7316 obj.remove_item();
7317 return !!wear_item( it );
7318 }
7319 } );
7320
7321 for( auto &e : worn ) {
7322 if( e.can_holster( *obj ) ) {
7323 auto ptr = dynamic_cast<const holster_actor *>( e.type->get_use( "holster" )->get_actor_ptr() );
7324 opts.emplace_back( dispose_option{
7325 string_format( _( "Store in %s" ), e.tname() ), true, e.invlet,
7326 item_store_cost( *obj, e, false, ptr->draw_cost ),
7327 [this, ptr, &e, &obj] {
7328 return ptr->store( *this->as_player(), e, *obj );
7329 }
7330 } );
7331 }
7332 }
7333
7334 int w = utf8_width( menu.text, true ) + 4;
7335 for( const auto &e : opts ) {
7336 w = std::max( w, utf8_width( e.prompt, true ) + 4 );
7337 }
7338 for( auto &e : opts ) {
7339 e.prompt += std::string( w - utf8_width( e.prompt, true ), ' ' );
7340 }
7341
7342 menu.text.insert( 0, 2, ' ' ); // add space for UI hotkeys
7343 menu.text += std::string( w + 2 - utf8_width( menu.text, true ), ' ' );
7344 menu.text += _( " | Moves " );
7345
7346 for( const auto &e : opts ) {
7347 menu.addentry( -1, e.enabled, e.invlet, string_format( e.enabled ? "%s | %-7d" : "%s |",
7348 e.prompt, e.moves ) );
7349 }
7350
7351 menu.query();
7352 if( menu.ret >= 0 ) {
7353 return opts[menu.ret].action();
7354 }
7355 return false;
7356}
int item_handling_cost(const item &it, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
Calculate (but do not deduct) the number of moves required when handling (e.g.
Definition: character.cpp:7470
std::optional< std::list< item >::iterator > wear_item(const item &to_wear, bool interactive=true)
Wear a copy of specified item.
Definition: character.cpp:2128
int item_wear_cost(const item &it) const
Calculate (but do not deduct) the number of moves required to wear an item.
Definition: character.cpp:7510
int item_store_cost(const item &it, const item &container, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
Calculate (but do not deduct) the number of moves required when storing an item in a container.
Definition: character.cpp:7495
ret_val< bool > can_wear(const item &it, bool with_equip_change=false) const
Check character capable of wearing an item.
Definition: character.cpp:2761
Holster a weapon.
Definition: iuse_actor.h:842
void add_item_keep_invlet(item newit)
Definition: inventory.cpp:385
void remove_item()
Removes the selected item from the game.
bool spill_contents(Character &c)
Unloads the item's contents.
Definition: item.cpp:7084
bool is_bucket_nonempty() const
Definition: item.cpp:6770
const void * ptr(const T *p)
\rst Converts p to const void* for pointer formatting.
@ prompt
Definition: pickup.h:30

References _, action, inventory::add_item_keep_invlet(), uilist::addentry(), Creature::as_player(), can_wear(), deliberate, enabled, inv, item_handling_cost(), item_store_cost(), item_wear_cost(), Creature::moves, pickup::prompt, ptr(), put_into_vehicle_or_drop(), uilist::query(), visitable< T >::remove_item(), uilist::ret, string_format(), uilist::text, inventory::unsort(), utf8_width(), volume_capacity(), volume_carried(), wear_item(), and worn.

Referenced by activate_bionic(), item::reload(), and unwield().

◆ do_damage_for_bionic_failure()

void Character::do_damage_for_bionic_failure ( int  min_damage,
int  max_damage 
)

Definition at line 2431 of file bionics.cpp.

2432{
2433 std::set<bodypart_id> bp_hurt;
2434 for( const bodypart_id &bp : get_all_body_parts() ) {
2435 if( has_effect( effect_under_op, bp->token ) ) {
2436 if( bp_hurt.count( bp->main_part ) > 0 ) {
2437 continue;
2438 }
2439 bp_hurt.emplace( bp->main_part );
2440 }
2441 }
2442
2443 if( bp_hurt.empty() ) {
2444 // If no bodypart associetd with bionic- just damage torso.
2445 // Special check for power storage - it does not belong to any body part.
2446 bp_hurt.emplace( bodypart_str_id( "torso" ) );
2447 }
2448
2449 for( const bodypart_id &bp : bp_hurt ) {
2450 int damage = rng( min_damage, max_damage );
2451 int hp = get_hp( bp );
2452 if( damage >= hp && ( bp == bodypart_str_id( "head" ) || bp == bodypart_str_id( "torso" ) ) ) {
2453 add_effect( effect_infected, 1_hours, bp->token );
2454 add_msg_player_or_npc( m_bad, _( "Your %s is infected." ), _( "<npcname>'s %s is infected." ),
2456 damage = hp * 0.8f;
2457 }
2458 apply_damage( this, bp, damage, true );
2459 if( damage > 15 )
2460 add_msg_player_or_npc( m_bad, _( "Your %s is severely damaged." ),
2461 _( "<npcname>'s %s is severely damaged." ),
2463 else
2464 add_msg_player_or_npc( m_bad, _( "Your %s is damaged." ), _( "<npcname>'s %s is damaged." ),
2466
2467 }
2468}
static const efftype_id effect_under_op("under_operation")
static const efftype_id effect_infected("infected")
std::string body_part_name_accusative(body_part bp, int number)
Returns the matching accusative name of the body_part token, i.e.
Definition: bodypart.cpp:331
virtual int get_hp() const
Definition: creature.cpp:1699

References _, Creature::add_effect(), Creature::add_msg_player_or_npc(), apply_damage(), body_part_name_accusative(), effect_infected, effect_under_op, Creature::get_all_body_parts(), Creature::get_hp(), Creature::has_effect(), hp, m_bad, and rng().

Referenced by bionics_install_failure(), and bionics_uninstall_failure().

◆ do_skill_rust()

void Character::do_skill_rust ( )
protected

Definition at line 3599 of file character.cpp.

3600{
3601 const int rust_rate_tmp = rust_rate();
3602 static const std::string PRED2( "PRED2" );
3603 static const std::string PRED3( "PRED3" );
3604 static const std::string PRED4( "PRED4" );
3605 for( std::pair<const skill_id, SkillLevel> &pair : *_skills ) {
3606 const Skill &aSkill = *pair.first;
3607 SkillLevel &skill_level_obj = pair.second;
3608
3609 if( aSkill.is_combat_skill() &&
3610 ( ( has_trait_flag( PRED2 ) && calendar::once_every( 8_hours ) ) ||
3611 ( has_trait_flag( PRED3 ) && calendar::once_every( 4_hours ) ) ||
3612 ( has_trait_flag( PRED4 ) && calendar::once_every( 3_hours ) ) ) ) {
3613 // Their brain is optimized to remember this
3614 if( one_in( 13 ) ) {
3615 // They've already passed the roll to avoid rust at
3616 // this point, but print a message about it now and
3617 // then.
3618 //
3619 // 13 combat skills.
3620 // This means PRED2/PRED3/PRED4 think of hunting on
3621 // average every 8/4/3 hours, enough for immersion
3622 // without becoming an annoyance.
3623 //
3624 add_msg_if_player( _( "Your heart races as you recall your most recent hunt." ) );
3625 mod_stim( 1 );
3626 }
3627 continue;
3628 }
3629
3630 const bool charged_bio_mem = get_power_level() > bio_memory->power_trigger &&
3632 const int oldSkillLevel = skill_level_obj.level();
3633 if( skill_level_obj.rust( charged_bio_mem, rust_rate_tmp ) ) {
3635 _( "Your knowledge of %s begins to fade, but your memory banks retain it!" ), aSkill.name() );
3637 }
3638 const int newSkill = skill_level_obj.level();
3639 if( newSkill < oldSkillLevel ) {
3640 add_msg_if_player( m_bad, _( "Your skill in %s has reduced to %d!" ), aSkill.name(), newSkill );
3641 }
3642 }
3643}
bool has_trait_flag(const std::string &b) const
Returns true if player has a trait with a flag.
Definition: mutation.cpp:106
int rust_rate() const
Returns the player's skill rust rate.
Definition: character.cpp:3393
void mod_stim(int mod)
Definition: character.cpp:7063
int level() const
Definition: skill.h:125
bool rust(bool charged_bio_mem, int character_rate)
Definition: skill.cpp:269
Definition: skill.h:33
std::string name() const
Definition: skill.h:68
bool is_combat_skill() const
Definition: skill.cpp:211
units::energy power_trigger
Power cost when the bionic's special effect is triggered.
Definition: bionics.h:43

References _, _skills, Creature::add_msg_if_player(), bio_memory, get_power_level(), has_active_bionic(), has_trait_flag(), Skill::is_combat_skill(), SkillLevel::level(), m_bad, m_warning, mod_power_level(), mod_stim(), Skill::name(), calendar::once_every(), one_in(), bionic_data::power_trigger, SkillLevel::rust(), and rust_rate().

Referenced by update_body().

◆ dodge_roll()

float Character::dodge_roll ( )
overridevirtual

Implements Creature.

Definition at line 909 of file melee.cpp.

910{
911 return get_dodge() * 5;
912}
float get_dodge() const override
Definition: melee.cpp:866

References get_dodge().

◆ drench()

void Character::drench ( int  saturation,
const body_part_set flags,
bool  ignore_waterproof 
)

Drenches the player with water, saturation is the percent gotten wet.

Definition at line 1824 of file suffer.cpp.

1825{
1826 if( saturation < 1 ) {
1827 return;
1828 }
1829
1830 // OK, water gets in your AEP suit or whatever. It wasn't built to keep you dry.
1832 ( !ignore_waterproof && is_waterproof( flags ) ) ) {
1833 return;
1834 }
1835
1836 // Make the body wet
1837 for( const body_part bp : all_body_parts ) {
1838 // Different body parts have different size, they can only store so much water
1839 int bp_wetness_max = 0;
1840 if( flags.test( bp ) ) {
1841 bp_wetness_max = drench_capacity[bp];
1842 }
1843
1844 if( bp_wetness_max == 0 ) {
1845 continue;
1846 }
1847 // Different sources will only make the bodypart wet to a limit
1848 int source_wet_max = saturation * bp_wetness_max * 2 / 100;
1849 int wetness_increment = ignore_waterproof ? 100 : 2;
1850 // Respect maximums
1851 const int wetness_max = std::min( source_wet_max, bp_wetness_max );
1852 if( body_wetness[bp] < wetness_max ) {
1853 body_wetness[bp] = std::min( wetness_max, body_wetness[bp] + wetness_increment );
1854 }
1855 }
1856
1859 get_value( "waterproof_scent" ).empty() ) {
1860 add_msg_if_player( m_info, _( "The water wash away the scent." ) );
1861 restore_scent();
1862 }
1863
1864 if( is_weak_to_water() ) {
1865 add_msg_if_player( m_bad, _( "You feel the water burning your skin." ) );
1866 }
1867
1868 // Remove onfire effect
1869 if( saturation > 10 || x_in_y( saturation, 10 ) ) {
1871 }
1872}
bool is_waterproof(const body_part_set &parts) const
Definition: character.cpp:8997
bool is_weak_to_water() const
Definition: mutation.cpp:412
void restore_scent()
restore scent after masked_scent effect run out or is removed by water
Definition: character.cpp:8766
static const trait_id trait_DEBUG_NOTEMP("DEBUG_NOTEMP")
static const efftype_id effect_masked_scent("masked_scent")
static const trait_id trait_SHELL2("SHELL2")
static const efftype_id effect_onfire("onfire")

References _, Creature::add_msg_if_player(), all_body_parts, body_wetness, bp_torso, drench_capacity, effect_masked_scent, effect_onfire, Creature::get_value(), has_active_mutation(), Creature::has_effect(), has_trait(), is_waterproof(), is_weak_to_water(), m_bad, m_info, Creature::remove_effect(), restore_scent(), body_part_set::test(), trait_DEBUG_NOTEMP, trait_SHELL2, and x_in_y().

Referenced by character_funcs::do_pause(), game::place_player(), and avatar_action::swim().

◆ drench_mut_calc()

void Character::drench_mut_calc ( )

Recalculates mutation drench protection for all bodyparts (ignored/good/neutral stats)

Definition at line 7816 of file character.cpp.

7817{
7818 for( const body_part bp : all_body_parts ) {
7819 int ignored = 0;
7820 int neutral = 0;
7821 int good = 0;
7822
7823 for( const trait_id &iter : get_mutations() ) {
7824 const mutation_branch &mdata = iter.obj();
7825 const auto wp_iter = mdata.protection.find( bp );
7826 if( wp_iter != mdata.protection.end() ) {
7827 ignored += wp_iter->second.x;
7828 neutral += wp_iter->second.y;
7829 good += wp_iter->second.z;
7830 }
7831 }
7832
7833 mut_drench[bp][WT_GOOD] = good;
7835 mut_drench[bp][WT_IGNORED] = ignored;
7836 }
7837}
@ good
Item should display as green (action possible at the moment)
std::map< body_part, tripoint > protection
Definition: mutation.h:267

References all_body_parts, get_mutations(), mut_drench, neutral, mutation_branch::protection, WT_GOOD, WT_IGNORED, and WT_NEUTRAL.

Referenced by avatar::load(), mutate_towards(), remove_mutation(), and game::start_game().

◆ drop() [1/2]

void Character::drop ( const drop_locations what,
const tripoint target,
bool  stash = false 
)
virtual

Reimplemented in npc.

Definition at line 2474 of file character.cpp.

2476{
2477 if( what.empty() ) {
2478 return;
2479 }
2480
2481 if( rl_dist( pos(), target ) > 1 || !( stash || get_map().can_put_items( target ) ) ) {
2482 add_msg_player_or_npc( m_info, _( "You can't place items here!" ),
2483 _( "<npcname> can't place items here!" ) );
2484 return;
2485 }
2486
2487 if( stash ) {
2488 assign_activity( stash_activity_actor( *this, what, target - pos() ) );
2489 } else {
2490 assign_activity( drop_activity_actor( *this, what, false, target - pos() ) );
2491 }
2492}

References _, Creature::add_msg_player_or_npc(), assign_activity(), get_map(), m_info, pos(), and rl_dist().

◆ drop() [2/2]

void Character::drop ( item_location  loc,
const tripoint where 
)

Drops an item to the specified location.

Definition at line 2452 of file character.cpp.

2453{
2454 item &oThisItem = *loc;
2455 if( is_wielding( oThisItem ) ) {
2456 const auto ret = can_unwield( *loc );
2457
2458 if( !ret.success() ) {
2459 add_msg( m_info, "%s", ret.c_str() );
2460 return;
2461 }
2462 } else if( is_wearing( oThisItem ) ) {
2463 const auto ret = as_player()->can_takeoff( *loc );
2464
2465 if( !ret.success() ) {
2466 add_msg( m_info, "%s", ret.c_str() );
2467 return;
2468 }
2469 }
2470
2471 drop( { drop_location( loc, loc->count() ) }, where );
2472}
ret_val< bool > can_takeoff(const item &it, const std::list< item > *res=nullptr) const
Check if character is capable of taking off given item.
Definition: character.cpp:3021
void drop(item_location loc, const tripoint &where)
Drops an item to the specified location.
Definition: character.cpp:2452
iuse_location drop_location

References add_msg(), Creature::as_player(), can_takeoff(), can_unwield(), item::count(), drop(), is_wearing(), is_wielding(), m_info, and cata::hash64_detail::ret.

Referenced by game::drop(), npc::drop(), drop(), game::drop_in_direction(), monexamine::give_items_to(), harvest_common(), i_add_or_drop(), examine_item_menu::run(), suffer_from_schizophrenia(), and takeoff().

◆ drop_invalid_inventory()

void Character::drop_invalid_inventory ( )

Definition at line 3190 of file character.cpp.

3191{
3192 bool dropped_liquid = false;
3193 for( const std::list<item> *stack : inv.const_slice() ) {
3194 const item &it = stack->front();
3195 if( it.made_of( LIQUID ) ) {
3196 dropped_liquid = true;
3197 get_map().add_item_or_charges( pos(), it );
3198 // must be last
3199 i_rem( &it );
3200 }
3201 }
3202 if( dropped_liquid ) {
3203 add_msg_if_player( m_bad, _( "Liquid from your inventory has leaked onto the ground." ) );
3204 }
3205
3206 if( volume_carried() > volume_capacity() ) {
3207 auto items_to_drop = inv.remove_randomly_by_volume( volume_carried() - volume_capacity() );
3209 }
3210}
std::list< item > remove_randomly_by_volume(const units::volume &volume)
Randomly select items until the volume quota is filled.
Definition: inventory.cpp:758
const_invslice const_slice() const
Definition: inventory.cpp:143

References _, map::add_item_or_charges(), Creature::add_msg_if_player(), inventory::const_slice(), get_map(), i_rem(), inv, LIQUID, m_bad, item::made_of(), pos(), put_into_vehicle_or_drop(), inventory::remove_randomly_by_volume(), tumbling, volume_capacity(), and volume_carried().

Referenced by absorb_hit(), player_activity::do_turn(), npc::execute_action(), process_turn(), and npc_trading::trade().

◆ eat()

bool Character::eat ( item food,
bool  force = false 
)

Used for eating entered comestible, returns true if comestible is successfully eaten.

Definition at line 828 of file consumption.cpp.

829{
830 if( !food.is_food() ) {
831 return false;
832 }
833
834 const auto ret = force ? can_eat( food ) : will_eat( food, is_player() );
835 if( !ret.success() ) {
836 return false;
837 }
838
839 if( has_effect( effect_bloated ) &&
840 ( compute_effective_nutrients( food ).kcal > 0 || food.get_comestible()->quench > 0 ) &&
841 !food.has_flag( flag_NO_BLOAT ) ) {
842 add_msg_if_player( _( "You force yourself to vomit to make space for %s." ), food.tname() );
843 vomit();
844 }
845
846 int charges_used = 0;
847 if( food.type->has_use() ) {
848 if( !food.type->can_use( "DOGFOOD" ) &&
849 !food.type->can_use( "CATFOOD" ) &&
850 !food.type->can_use( "BIRDFOOD" ) &&
851 !food.type->can_use( "CATTLEFODDER" ) ) {
852 charges_used = food.type->invoke( *this->as_player(), food, pos() );
853 if( charges_used <= 0 ) {
854 return false;
855 }
856 }
857 }
858
859 // Note: the block below assumes we decided to eat it
860 // No coming back from here
861
862 const int nutr = nutrition_for( food );
863 const bool spoiled = food.rotten();
864
865 // The item is solid food
866 const bool chew = food.get_comestible()->comesttype == comesttype_FOOD ||
868 // This item is a drink and not a solid food (and not a thick soup)
869 const bool drinkable = !chew && food.get_comestible()->comesttype == comesttype_DRINK;
870 // If neither of the above is true then it's a drug and shouldn't get mealtime penalty/bonus
871
872 const bool saprophage = has_trait( trait_SAPROPHAGE );
873 if( spoiled && !saprophage ) {
874 add_msg_if_player( m_bad, _( "Ick, this %s doesn't taste so good…" ), food.tname() );
877 add_effect( effect_foodpoison, rng( 6_minutes, ( nutr + 1 ) * 6_minutes ) );
878 }
879 } else if( spoiled && saprophage ) {
880 add_msg_if_player( m_good, _( "Mmm, this %s tastes delicious…" ), food.tname() );
881 }
882 // Store the fact that the food was cold to later reapply it to the rest of the stack, to prevent rot.
883 // Note: Implemented to fix display error when eating reheated food.
884 bool food_was_cold = food.has_flag( flag_COLD );
885 bool food_was_very_cold = food.has_flag( flag_VERY_COLD );
886
887 if( !consume_effects( food ) ) {
888 // Already consumed by using `food.type->invoke`?
889 if( charges_used > 0 ) {
890 food.mod_charges( -charges_used );
891 }
892 return false;
893 }
894 food.mod_charges( -1 );
895
896 const bool amorphous = has_trait( trait_AMORPHOUS );
897 int mealtime = 250;
898 if( drinkable || chew ) {
899 // Those bonuses/penalties only apply to food
900 // Not to smoking weed or applying bandages!
903 mealtime /= 2;
904 } else if( has_trait( trait_SHARKTEETH ) ) {
905 // SHARKBAIT! HOO HA HA!
906 mealtime /= 3;
907 } else if( has_trait( trait_GOURMAND ) ) {
908 // Don't stack those two - that would be 25 moves per item
909 mealtime -= 100;
910 }
911
912 if( has_trait( trait_BEAK_HUM ) && !drinkable ) {
913 // Much better than PROBOSCIS but still optimized for fluids
914 mealtime += 200;
915 } else if( has_trait( trait_SABER_TEETH ) ) {
916 // They get In The Way
917 mealtime += 250;
918 }
919
920 if( amorphous ) {
921 mealtime *= 1.1;
922 // Minor speed penalty for having to flow around it
923 // rather than just grab & munch
924 }
925 }
926
927 moves -= mealtime;
928
929 // If it's poisonous... poison us.
930 // TODO: Move this to a flag
931 if( food.poison > 0 && !has_trait( trait_POISRESIST ) &&
933 if( food.poison >= rng( 2, 4 ) ) {
934 add_effect( effect_poison, food.poison * 10_minutes );
935 }
936
937 add_effect( effect_foodpoison, food.poison * 30_minutes );
938 }
939
940 if( food.has_flag( flag_HIDDEN_HALLU ) ) {
941 if( !has_effect( effect_hallu ) ) {
942 add_effect( effect_hallu, 6_hours );
943 }
944 }
945
946 if( amorphous ) {
947 add_msg_player_or_npc( _( "You assimilate your %s." ), _( "<npcname> assimilates a %s." ),
948 food.tname() );
949 } else if( drinkable ) {
950 add_msg_player_or_npc( _( "You drink your %s." ), _( "<npcname> drinks a %s." ),
951 food.tname() );
952 } else if( chew ) {
953 add_msg_player_or_npc( _( "You eat your %s." ), _( "<npcname> eats a %s." ),
954 food.tname() );
955 }
956
957 if( food_was_cold ) {
958 food.set_flag( flag_COLD );
959 }
960
961 if( food_was_very_cold ) {
962 food.set_flag( flag_VERY_COLD );
963 }
964
965 if( food.get_comestible()->tool->tool ) {
966 // Tools like lighters get used
967 use_charges( food.get_comestible()->tool, 1 );
968 }
969
971 add_effect( effect_fungus, 1_turns, num_bp );
972 }
973
974 // Chance to become parasitised
976 if( food.get_comestible()->parasites > 0 && !food.has_flag( flag_NO_PARASITES ) &&
977 one_in( food.get_comestible()->parasites ) ) {
978 switch( rng( 0, 3 ) ) {
979 case 0:
980 add_effect( effect_tapeworm, 1_turns, num_bp );
981 break;
982 case 1:
983 if( !has_trait( trait_ACIDBLOOD ) ) {
985 }
986 break;
987 case 2:
989 break;
990 case 3:
992 }
993 }
994 }
995
996 for( const std::pair<const diseasetype_id, int> &elem : food.get_comestible()->contamination ) {
997 if( rng( 1, 100 ) <= elem.second ) {
998 expose_to_disease( elem.first );
999 }
1000 }
1001
1002 consumption_history->elems.emplace_back( food );
1003 // Clean out consumption_history so it doesn't get bigger than needed.
1004 while( consumption_history->elems.front().time < calendar::turn - 2_days ) {
1005 consumption_history->elems.pop_front();
1006 }
1007
1008 return true;
1009}
void expose_to_disease(diseasetype_id dis_type)
Determine if character is susceptible to dis_type and if so apply the symptoms.
Definition: character.cpp:1564
pimpl< consumption_history_t > consumption_history
Definition: character.h:1591
ret_val< edible_rating > will_eat(const item &food, bool interactive=false) const
Same as can_eat, but takes consequences into account.
bool rotten() const
returns true if item is now rotten after all shelf life has elapsed
Definition: item.h:849
void mod_charges(int mod)
Modify the charges of this item, only use for items counted by charges! The item must have enough cha...
Definition: item.cpp:9750
int poison
Definition: item.h:2204
item & set_flag(const std::string &flag)
Idempotent filter setting an item specific flag.
Definition: item.cpp:5357
static const efftype_id effect_bloodworms("bloodworms")
static const efftype_id effect_fungus("fungus")
static const std::string flag_FUNGAL_VECTOR("FUNGAL_VECTOR")
static const trait_id trait_SHARKTEETH("SHARKTEETH")
static const trait_id trait_EATDEAD("EATDEAD")
static const trait_id trait_SABER_TEETH("SABER_TEETH")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const efftype_id effect_hallu("hallu")
static const std::string flag_VERY_COLD("VERY_COLD")
static const trait_id trait_BEAK_HUM("BEAK_HUM")
static const trait_id trait_PARAIMMUNE("PARAIMMUNE")
static const trait_id trait_MANDIBLES("MANDIBLES")
static const std::string flag_HIDDEN_HALLU("HIDDEN_HALLU")
static const efftype_id effect_paincysts("paincysts")
static const std::string flag_NO_PARASITES("NO_PARASITES")
static const trait_id trait_AMORPHOUS("AMORPHOUS")
static const trait_id trait_MOUTH_TENTACLES("MOUTH_TENTACLES")
static const efftype_id effect_poison("poison")
static const std::string flag_COLD("COLD")
static const efftype_id effect_foodpoison("foodpoison")
static const trait_id trait_FANGS_SPIDER("FANGS_SPIDER")
static const trait_id trait_POISRESIST("POISRESIST")
static const trait_id trait_ACIDBLOOD("ACIDBLOOD")
static const efftype_id effect_brainworms("brainworms")
int chew(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:1103

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), Creature::as_player(), bio_digestion, can_eat(), itype::can_use(), iuse::chew(), comesttype_DRINK(), comesttype_FOOD(), compute_effective_nutrients(), consume_effects(), consumption_history, effect_bloated, effect_bloodworms, effect_brainworms, effect_foodpoison, effect_fungus, effect_hallu, effect_paincysts, effect_poison, effect_tapeworm, expose_to_disease(), flag_COLD(), flag_FUNGAL_VECTOR(), flag_HIDDEN_HALLU(), flag_NO_BLOAT(), flag_NO_PARASITES(), flag_USE_EAT_VERB(), flag_VERY_COLD(), item::get_comestible(), has_bionic(), Creature::has_effect(), item::has_flag(), has_trait(), itype::has_use(), itype::invoke(), item::is_food(), Creature::is_player(), m_bad, m_good, item::mod_charges(), Creature::moves, num_bp, nutrition_for(), one_in(), item::poison, pos(), cata::hash64_detail::ret, rng(), item::rotten(), item::set_flag(), item::tname(), trait_ACIDBLOOD, trait_AMORPHOUS, trait_BEAK_HUM, trait_EATDEAD, trait_FANGS_SPIDER, trait_GOURMAND, trait_M_IMMUNE, trait_MANDIBLES, trait_MOUTH_TENTACLES, trait_PARAIMMUNE, trait_POISRESIST, trait_SABER_TEETH, trait_SAPROPHAGE, trait_SAPROVORE, trait_SHARKTEETH, calendar::turn, item::type, use_charges(), vomit(), and will_eat().

Referenced by consume_item(), drink_nectar(), avatar_action::eat_here(), iexamine::flower_poppy(), vehicle::interact_with(), iexamine::keg(), and try_consume().

◆ encumb()

◆ enforce_minimum_healing()

void Character::enforce_minimum_healing ( )

Definition at line 4635 of file character.cpp.

4636{
4637 for( const bodypart_id &bp : get_all_body_parts() ) {
4638 if( get_part_healed_total( bp ) <= 0 ) {
4639 heal( bp, 1 );
4640 }
4641 set_part_healed_total( bp, 0 );
4642 }
4643}
void heal(const bodypart_id &healed, int dam)
Heals a body_part for dam.
Definition: character.cpp:8646
void set_part_healed_total(const bodypart_id &id, int set)
Definition: creature.cpp:1631
int get_part_healed_total(const bodypart_id &id) const
Definition: creature.cpp:1616

References Creature::get_all_body_parts(), Creature::get_part_healed_total(), heal(), and Creature::set_part_healed_total().

Referenced by update_body().

◆ enough_power_for()

bool Character::enough_power_for ( const bionic_id bid) const

Definition at line 1956 of file character.cpp.

1957{
1958 return power_level >= bid->power_activate;
1959}
units::energy power_level
Definition: character.h:2250

References bionic_data::power_activate, and power_level.

Referenced by activate_bionic(), and iexamine::fireplace().

◆ enumerate_unmet_requirements()

std::string Character::enumerate_unmet_requirements ( const item it,
const item context = item() 
) const

Returns a string of missed requirements (both stats and skills)

Definition at line 3369 of file character.cpp.

3370{
3371 std::vector<std::string> unmet_reqs;
3372
3373 const auto check_req = [ &unmet_reqs ]( const std::string & name, int cur, int req ) {
3374 if( cur < req ) {
3375 unmet_reqs.push_back( string_format( "%s %d", name, req ) );
3376 }
3377 };
3378
3379 check_req( _( "strength" ), get_str(), it.get_min_str() );
3380 check_req( _( "dexterity" ), get_dex(), it.type->min_dex );
3381 check_req( _( "intelligence" ), get_int(), it.type->min_int );
3382 check_req( _( "perception" ), get_per(), it.type->min_per );
3383
3384 for( const auto &elem : it.type->min_skills ) {
3385 check_req( context.contextualize_skill( elem.first )->name(),
3386 get_skill_level( elem.first, context ),
3387 elem.second );
3388 }
3389
3390 return enumerate_as_string( unmet_reqs );
3391}
int get_min_str() const
Definition: item.cpp:10073
skill_id contextualize_skill(const skill_id &id) const
Puts the skill in context of the item.
Definition: item.cpp:9995
int min_dex
Definition: itype.h:906
int min_int
Definition: itype.h:907
int min_per
Definition: itype.h:908
std::map< skill_id, int > min_skills
Definition: itype.h:904

References _, item::contextualize_skill(), enumerate_as_string(), get_dex(), get_int(), item::get_min_str(), get_per(), get_skill_level(), get_str(), itype::min_dex, itype::min_int, itype::min_per, itype::min_skills, name, Skill::name(), string_format(), and item::type.

Referenced by can_use(), and gunmod_inventory_preset::get_denial().

◆ env_surgery_bonus()

float Character::env_surgery_bonus ( int  radius)

Calculate skill bonus from tiles in radius.

Definition at line 2310 of file bionics.cpp.

2311{
2312 float bonus = 1.0;
2313 map &here = get_map();
2314 for( const tripoint &cell : here.points_in_radius( pos(), radius ) ) {
2315 if( here.furn( cell )->surgery_skill_multiplier ) {
2316 bonus = std::max( bonus, *here.furn( cell )->surgery_skill_multiplier );
2317 }
2318 }
2319 return bonus;
2320}
furn_id furn(const tripoint &p) const
Definition: map.cpp:1412
std::optional< float > surgery_skill_multiplier
Definition: mapdata.h:521

References map::furn(), get_map(), map::points_in_radius(), pos(), and furn_t::surgery_skill_multiplier.

Referenced by bionics_adjusted_skill().

◆ environmental_revert_effect()

void Character::environmental_revert_effect ( )

Definition at line 787 of file character_turn.cpp.

788{
789 addictions.clear();
790 morale->clear();
791
794 set_thirst( 0 );
795 set_fatigue( 0 );
796 set_healthy( 0 );
797 set_healthy_mod( 0 );
798 set_stim( 0 );
799 set_pain( 0 );
800 set_painkiller( 0 );
801 set_rad( 0 );
803
806}
virtual void set_sleep_deprivation(int nsleep_deprivation)
Definition: character.cpp:4473
virtual void set_healthy_mod(int nhealthy_mod)
Definition: character.cpp:4278
virtual void set_stored_kcal(int kcal)
Setters for need values exclusive to characters.
Definition: character.cpp:4334
void set_pain(int npain) override
Sets new intensity of pain an reacts to it.
Definition: character.cpp:791
virtual void set_healthy(int nhealthy)
Setters for health values exclusive to characters.
Definition: character.cpp:4266
virtual void set_thirst(int nthirst)
Definition: character.cpp:4446
void set_all_parts_hp_to_max()
Definition: creature.cpp:1658

References addictions, max_stored_kcal(), morale, recalc_sight_limits(), reset_encumbrance(), Creature::set_all_parts_hp_to_max(), set_fatigue(), set_healthy(), set_healthy_mod(), set_pain(), set_painkiller(), set_rad(), set_sleep_deprivation(), set_stim(), set_stored_kcal(), and set_thirst().

◆ exclusive_flag_coverage()

body_part_set Character::exclusive_flag_coverage ( const std::string &  flag) const

Bitset of all the body parts covered only with items with flag (or nothing)

Definition at line 4068 of file character.cpp.

4069{
4071
4072 for( const auto &elem : worn ) {
4073 if( !elem.has_flag( flag ) ) {
4074 // Unset the parts covered by this item
4075 ret &= ~elem.get_covered_body_parts();
4076 }
4077 }
4078
4079 return ret;
4080}
static body_part_set all()
Definition: bodypart.h:246

References body_part_set::all(), cata::hash64_detail::ret, and worn.

Referenced by apply_wetness_morale(), mut_cbm_encumb(), mutation_attacks(), reset_stats(), and swim_speed().

◆ expose_to_disease()

void Character::expose_to_disease ( diseasetype_id  dis_type)

Determine if character is susceptible to dis_type and if so apply the symptoms.

Definition at line 1564 of file character.cpp.

1565{
1566 const std::optional<int> &healt_thresh = dis_type->health_threshold;
1567 if( healt_thresh && healt_thresh.value() < get_healthy() ) {
1568 return;
1569 }
1570 const std::set<body_part> &bps = dis_type->affected_bodyparts;
1571 if( !bps.empty() ) {
1572 for( const body_part &bp : bps ) {
1573 add_effect( dis_type->symptoms, rng( dis_type->min_duration, dis_type->max_duration ), bp,
1574 rng( dis_type->min_intensity, dis_type->max_intensity ) );
1575 }
1576 } else {
1577 add_effect( dis_type->symptoms, rng( dis_type->min_duration, dis_type->max_duration ), num_bp,
1578 rng( dis_type->min_intensity, dis_type->max_intensity ) );
1579 }
1580}
virtual int get_healthy() const
Getters for health values exclusive to characters.
Definition: character.cpp:4165
time_duration min_duration
Definition: disease.h:26
std::optional< int > health_threshold
If not empty this sets the health threshold above which you're immune to the disease.
Definition: disease.h:33
int max_intensity
Definition: disease.h:29
efftype_id symptoms
effect applied by this disease
Definition: disease.h:35
std::set< body_part > affected_bodyparts
Affected body parts.
Definition: disease.h:31
int min_intensity
Definition: disease.h:28
time_duration max_duration
Definition: disease.h:27

References Creature::add_effect(), disease_type::affected_bodyparts, get_healthy(), disease_type::health_threshold, disease_type::max_duration, disease_type::max_intensity, disease_type::min_duration, disease_type::min_intensity, num_bp, rng(), and disease_type::symptoms.

Referenced by eat().

◆ extended_description()

std::string Character::extended_description ( ) const
overridevirtual

Implements Creature.

Reimplemented in npc.

Definition at line 6500 of file character.cpp.

6501{
6502 std::string ss;
6503 if( is_player() ) {
6504 // <bad>This is me, <player_name>.</bad>
6505 ss += string_format( _( "This is you - %s." ), name );
6506 } else {
6507 ss += string_format( _( "This is %s, %s" ), name, male ? _( "Male" ) : _( "Female" ) );
6508 }
6509
6510 ss += "\n--\n";
6511
6512 const std::vector<bodypart_id> &bps = get_all_body_parts( true );
6513 // Find length of bp names, to align
6514 // accumulate looks weird here, any better function?
6515 int longest = std::accumulate( bps.begin(), bps.end(), 0,
6516 []( int m, bodypart_id bp ) {
6517 return std::max( m, utf8_width( body_part_name_as_heading( bp->token, 1 ) ) );
6518 } );
6519
6520 // This is a stripped-down version of the body_window function
6521 // This should be extracted into a separate function later on
6522 for( const bodypart_id &bp : bps ) {
6523 // Hide appendix from the player
6524 if( bp->id.str() == "num_bp" ) {
6525 continue;
6526 }
6527 const std::string &bp_heading = body_part_name_as_heading( bp->token, 1 );
6528
6529 const nc_color state_col = limb_color( bp, true, true, true );
6530 nc_color name_color = state_col;
6531 std::pair<std::string, nc_color> hp_bar = get_hp_bar( get_part_hp_cur( bp ), get_part_hp_max( bp ),
6532 false );
6533
6534 ss += colorize( left_justify( bp_heading, longest ), name_color );
6535 ss += colorize( hp_bar.first, hp_bar.second );
6536 // Trailing bars. UGLY!
6537 // TODO: Integrate into get_hp_bar somehow
6538 ss += colorize( std::string( 5 - utf8_width( hp_bar.first ), '.' ), c_white );
6539 ss += "\n";
6540 }
6541
6542 ss += "--\n";
6543 ss += _( "Wielding:" ) + std::string( " " );
6544 const item &weapon = primary_weapon();
6545 if( weapon.is_null() ) {
6546 ss += _( "Nothing" );
6547 } else {
6548 ss += weapon.tname();
6549 }
6550
6551 ss += "\n";
6552 ss += _( "Wearing:" ) + std::string( " " );
6553 ss += enumerate_as_string( worn.begin(), worn.end(), []( const item & it ) {
6554 return it.tname();
6555 } );
6556
6557 return replace_colors( ss );
6558}
std::string left_justify(const std::string &str, const int width, const bool ignore_tags)
bool male
Definition: character.h:1567
std::string replace_colors(std::string text)
Replace special color tags (e.g.

References _, body_part_name_as_heading(), c_white, colorize(), enumerate_as_string(), Creature::get_all_body_parts(), get_hp_bar(), Creature::get_part_hp_cur(), Creature::get_part_hp_max(), int_id< T >::id(), item::is_null(), Creature::is_player(), left_justify(), limb_color(), male, name, primary_weapon(), replace_colors(), string_format(), item::tname(), utf8_width(), and worn.

Referenced by npc::extended_description().

◆ extraEncumbrance()

int Character::extraEncumbrance ( layer_level  level,
int  bp 
) const

Get encumbrance penalty per layer & body part.

Definition at line 3714 of file character.cpp.

3715{
3716 return encumbrance_cache->elems[bp].layer_penalty_details[static_cast<int>( level )].total;
3717}

References encumbrance_cache.

◆ fall_asleep() [1/2]

void Character::fall_asleep ( )

Adds "sleep" to the player.

Definition at line 9274 of file character.cpp.

9275{
9276 // Communicate to the player that he is using items on the floor
9277 std::string item_name = is_snuggling();
9278 if( item_name == "many" ) {
9279 if( one_in( 15 ) ) {
9280 add_msg_if_player( _( "You nestle your pile of clothes for warmth." ) );
9281 } else {
9282 add_msg_if_player( _( "You use your pile of clothes for warmth." ) );
9283 }
9284 } else if( item_name != "nothing" ) {
9285 if( one_in( 15 ) ) {
9286 add_msg_if_player( _( "You snuggle your %s to keep warm." ), item_name );
9287 } else {
9288 add_msg_if_player( _( "You use your %s to keep warm." ), item_name );
9289 }
9290 }
9292 if( get_stored_kcal() > max_stored_kcal() - bmr() / 4 &&
9294 if( is_avatar() ) {
9295 g->memorial().add( pgettext( "memorial_male", "Entered hibernation." ),
9296 pgettext( "memorial_female", "Entered hibernation." ) );
9297 }
9298
9299 add_msg_if_player( _( "You enter hibernation." ) );
9300 fall_asleep( 7_days );
9301 } else {
9303 _( "You need to be nearly full of food and water to enter hibernation." ) );
9304 }
9305 }
9306
9307 fall_asleep( 10_hours ); // default max sleep time.
9308}
static const trait_id trait_HIBERNATE("HIBERNATE")
int bmr() const
Definition: character.cpp:6858
std::string is_snuggling() const
Checks to see if the player is using floor items to keep warm, and return the name of one such item i...
Definition: character.cpp:9327

References _, Creature::add_msg_if_player(), bmr(), fall_asleep(), g, get_stored_kcal(), get_thirst(), has_active_mutation(), Creature::is_avatar(), is_snuggling(), m_bad, max_stored_kcal(), one_in(), pgettext(), thirsty, and trait_HIBERNATE.

Referenced by check_needs_extremes(), fall_asleep(), iexamine::flower_poppy(), hardcoded_effects(), introduce_into_anesthesia(), marloss_common(), iuse::mycus(), process_one_effect(), suffer_from_stimulants(), suffer_while_awake(), try_reject_mutagen(), activity_handlers::try_sleep_do_turn(), and mutagen_iv_actor::use().

◆ fall_asleep() [2/2]

void Character::fall_asleep ( const time_duration duration)

Definition at line 9310 of file character.cpp.

9311{
9312 if( activity ) {
9313 if( activity.id() == ACT_TRY_SLEEP ) {
9315 } else {
9317 }
9318 }
9319 add_effect( effect_sleep, duration );
9320}
void cancel_activity()
Definition: character.cpp:9234
void set_to_null()
This replaces the former usage act.type = ACT_NULL

References ACT_TRY_SLEEP, activity, Creature::add_effect(), cancel_activity(), effect_sleep, player_activity::id(), and player_activity::set_to_null().

◆ fall_damage_mod()

float Character::fall_damage_mod ( ) const
overridevirtual

Returns multiplier on fall damage at low velocity (knockback/pit/1 z-level, not 5 z-levels)

Dexterity decreases damage from falling Dodge decreases damage from falling

Implements Creature.

Definition at line 10801 of file character.cpp.

10802{
10803 if( has_effect_with_flag( "EFFECT_FEATHER_FALL" ) ) {
10804 return 0.0f;
10805 }
10806 float ret = 1.0f;
10807
10808 // Ability to land properly is 2x as important as dexterity itself
10809 /** @EFFECT_DEX decreases damage from falling */
10810
10811 /** @EFFECT_DODGE decreases damage from falling */
10812 float dex_dodge = dex_cur / 2.0 + get_skill_level( skill_dodge );
10813 // Penalize for wearing heavy stuff
10814 const float average_leg_encumb = ( encumb( bp_leg_l ) + encumb( bp_leg_r ) ) / 2.0;
10815 dex_dodge -= ( average_leg_encumb + encumb( bp_torso ) ) / 10;
10816 // But prevent it from increasing damage
10817 dex_dodge = std::max( 0.0f, dex_dodge );
10818 // 100% damage at 0, 75% at 10, 50% at 20 and so on
10819 ret *= ( 100.0f - ( dex_dodge * 4.0f ) ) / 100.0f;
10820
10821 if( has_trait( trait_PARKOUR ) ) {
10822 ret *= 2.0f / 3.0f;
10823 }
10824
10825 // TODO: Bonus for Judo, mutations. Penalty for heavy weight (including mutations)
10826 return std::max( 0.0f, ret );
10827}
static const trait_id trait_PARKOUR("PARKOUR")
bool has_effect_with_flag(const std::string &flag, body_part bp=num_bp) const
Check if creature has any effect with the given flag.
Definition: creature.cpp:1228

References bp_leg_l, bp_leg_r, bp_torso, dex_cur, encumb(), get_skill_level(), Creature::has_effect_with_flag(), has_trait(), cata::hash64_detail::ret, skill_dodge, and trait_PARKOUR.

Referenced by impact(), and iexamine::ledge().

◆ feed_furnace_with()

bool Character::feed_furnace_with ( item it)

Recharge CBMs whenever possible.

Returns
true when recharging was successful.

Definition at line 1294 of file consumption.cpp.

1295{
1296 if( !can_feed_furnace_with( it ) ) {
1297 return false;
1298 }
1299 if( it.is_favorite &&
1300 !g->u.query_yn( _( "Are you sure you want to eat your favorited %s?" ), it.tname() ) ) {
1301 return false;
1302 }
1303
1304 const int consumed_charges = std::min( it.charges, it.charges_per_volume( furnace_max_volume ) );
1306
1307 if( energy == 0 ) {
1309 _( "You digest your %s, but fail to acquire energy from it." ),
1310 _( "<npcname> digests their %s for energy, but fails to acquire energy from it." ),
1311 it.tname() );
1312 } else if( is_max_power() ) {
1314 _( "You digest your %s, but you're fully powered already, so the energy is wasted." ),
1315 _( "<npcname> digests a %s for energy, they're fully powered already, so the energy is wasted." ),
1316 it.tname() );
1317 } else {
1318 const int profitable_energy = std::min( energy,
1320 if( it.count_by_charges() ) {
1322 vgettext( "You digest %d %s and recharge %d point of energy.",
1323 "You digest %d %s and recharge %d points of energy.",
1324 profitable_energy
1325 ),
1326 vgettext( "<npcname> digests %d %s and recharges %d point of energy.",
1327 "<npcname> digests %d %s and recharges %d points of energy.",
1328 profitable_energy
1329 ), consumed_charges, it.tname(), profitable_energy
1330 );
1331 } else {
1333 vgettext( "You digest your %s and recharge %d point of energy.",
1334 "You digest your %s and recharge %d points of energy.",
1335 profitable_energy
1336 ),
1337 vgettext( "<npcname> digests a %s and recharges %d point of energy.",
1338 "<npcname> digests a %s and recharges %d points of energy.",
1339 profitable_energy
1340 ), it.tname(), profitable_energy
1341 );
1342 }
1343 mod_power_level( units::from_kilojoule( profitable_energy ) );
1344 }
1345
1346 it.charges -= consumed_charges;
1347 mod_moves( -250 );
1348
1349 return true;
1350}
int get_acquirable_energy(const item &it, rechargeable_cbm cbm) const
bool can_feed_furnace_with(const item &it) const
Determine character's capability of recharging their CBMs.
bool is_max_power() const
Definition: character.cpp:1941
bool is_favorite
Definition: item.h:2239
quantity< int, energy_in_joule_tag > energy
Definition: units_energy.h:16
const char * vgettext(const char *msgid, const char *msgid_plural, size_t n)

References _, Creature::add_msg_player_or_npc(), can_feed_furnace_with(), item::charges, item::charges_per_volume(), item::count_by_charges(), units::from_kilojoule(), furnace, furnace_max_volume, g, get_acquirable_energy(), get_max_power_level(), get_power_level(), item::is_favorite, is_max_power(), m_info, Creature::mod_moves(), mod_power_level(), item::tname(), units::to_kilojoule(), and vgettext().

Referenced by consume_item().

◆ find_remote_fuel()

itype_id Character::find_remote_fuel ( bool  look_only = false)

Find fuel used by remote powered bionic.

Definition at line 1400 of file bionics.cpp.

1401{
1402 itype_id remote_fuel;
1403 map &here = get_map();
1404
1405 const std::vector<item *> cables = items_with( []( const item & it ) {
1406 return it.active && it.has_flag( flag_CABLE_SPOOL );
1407 } );
1408
1409 for( const item *cable : cables ) {
1410
1411 const std::optional<tripoint> target = cable->get_cable_target( this, pos() );
1412 if( !target ) {
1413 if( here.is_outside( pos() ) && !is_night( calendar::turn ) &&
1414 cable->get_var( "state" ) == "solar_pack_link" ) {
1415 if( !look_only ) {
1416 set_value( "sunlight", "1" );
1417 }
1418 remote_fuel = fuel_type_sun_light;
1419 }
1420
1421 if( cable->get_var( "state" ) == "UPS_link" ) {
1422 static const item_filter used_ups = [&]( const item & itm ) {
1423 return itm.get_var( "cable" ) == "plugged_in";
1424 };
1425 if( !look_only ) {
1426 if( has_charges( itype_UPS_off, 1, used_ups ) ) {
1428 units::to_kilojoule( max_power_level ), used_ups ) ) );
1429 } else if( has_charges( itype_adv_UPS_off, 1, used_ups ) ) {
1431 units::to_kilojoule( max_power_level ), used_ups ) ) );
1432 } else {
1433 set_value( "rem_battery", std::to_string( 0 ) );
1434 }
1435 }
1436 remote_fuel = fuel_type_battery;
1437 }
1438 continue;
1439 }
1440 const optional_vpart_position vp = here.veh_at( *target );
1441 if( !vp ) {
1442 continue;
1443 }
1444 if( !look_only ) {
1445 set_value( "rem_battery", std::to_string( vp->vehicle().fuel_left( fuel_type_battery,
1446 true ) ) );
1447 }
1448 remote_fuel = fuel_type_battery;
1449 }
1450
1451 return remote_fuel;
1452}
static const itype_id fuel_type_battery("battery")
bool is_night(const time_point &p)
Returns true if it's currently night time - after dusk and before dawn.
Definition: calendar.cpp:137
units::energy max_power_level
Definition: character.h:2251
bool is_outside(const tripoint &p) const
Definition: map.cpp:2625
int charges_of(const itype_id &what, int limit=INT_MAX, const std::function< bool(const item &)> &filter=return_true< item >, std::function< void(int)> visitor=nullptr) const
Count maximum available charges from this instance and any contained items.
Definition: visitable.cpp:946

References item::active, visitable< Character >::charges_of(), flag_CABLE_SPOOL(), fuel_type_battery, fuel_type_sun_light, get_map(), has_charges(), item::has_flag(), is_night(), map::is_outside(), visitable< Character >::items_with(), itype_adv_UPS_off, itype_UPS_off, max_power_level, pos(), Creature::set_value(), units::to_kilojoule(), to_string(), calendar::turn, and map::veh_at().

Referenced by burn_fuel(), iuse::cable_attach(), draw_bionics_titlebar(), and process_bionic().

◆ flag_encumbrance()

void Character::flag_encumbrance ( )

Flag encumbrance for updating.

Definition at line 1762 of file character.cpp.

1763{
1764 check_encumbrance = true;
1765}

References check_encumbrance.

Referenced by monexamine::attach_bag_to(), item::on_drop(), item::on_pickup(), and item::on_wield().

◆ floor_bedding_warmth()

int Character::floor_bedding_warmth ( const tripoint pos)
static

Warmth from terrain, furniture, vehicle furniture and traps.

Can be negative.

Definition at line 9470 of file character.cpp.

9471{
9472 map &here = get_map();
9473 const trap &trap_at_pos = here.tr_at( pos );
9474 const ter_id ter_at_pos = here.ter( pos );
9475 const furn_id furn_at_pos = here.furn( pos );
9476 int floor_bedding_warmth = 0;
9477
9478 const optional_vpart_position vp = here.veh_at( pos );
9479 const std::optional<vpart_reference> boardable = vp.part_with_feature( "BOARDABLE", true );
9480 // Search the floor for bedding
9481 if( furn_at_pos != f_null ) {
9483 } else if( !trap_at_pos.is_null() ) {
9485 } else if( boardable ) {
9486 floor_bedding_warmth += boardable->info().floor_bedding_warmth;
9487 } else if( ter_at_pos == t_improvised_shelter ) {
9488 floor_bedding_warmth -= 500;
9489 } else {
9490 floor_bedding_warmth -= 2000;
9491 }
9492
9493 return floor_bedding_warmth;
9494}
static int floor_bedding_warmth(const tripoint &pos)
Warmth from terrain, furniture, vehicle furniture and traps.
Definition: character.cpp:9470
const T & obj() const
Definition: ammo_effect.cpp:26
const trap & tr_at(const tripoint &p) const
Definition: map.cpp:5257
ter_id ter(const tripoint &p) const
Definition: map.cpp:1562
std::optional< vpart_reference > part_with_feature(const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2482
ter_id t_improvised_shelter
Definition: mapdata.cpp:718
int floor_bedding_warmth
Definition: mapdata.h:508
Definition: trap.h:86
int floor_bedding_warmth
Definition: trap.h:120

References f_null, floor_bedding_warmth(), furn_t::floor_bedding_warmth, trap::floor_bedding_warmth, map::furn(), get_map(), trap::is_null(), int_id< T >::obj(), optional_vpart_position::part_with_feature(), pos(), t_improvised_shelter, map::ter(), map::tr_at(), and map::veh_at().

Referenced by floor_bedding_warmth(), and floor_warmth().

◆ floor_item_warmth()

int Character::floor_item_warmth ( const tripoint pos)
static

Warmth from clothing on the floor.

Definition at line 9496 of file character.cpp.

9497{
9498 int item_warmth = 0;
9499
9500 const auto warm = [&item_warmth]( const auto & stack ) {
9501 for( const item &elem : stack ) {
9502 if( !elem.is_armor() ) {
9503 continue;
9504 }
9505 // Items that are big enough and covers the torso are used to keep warm.
9506 // Smaller items don't do as good a job
9507 if( elem.volume() > 250_ml &&
9508 ( elem.covers( bp_torso ) || elem.covers( bp_leg_l ) ||
9509 elem.covers( bp_leg_r ) ) ) {
9510 item_warmth += 60 * elem.get_warmth() * elem.volume() / 2500_ml;
9511 }
9512 }
9513 };
9514
9515 map &here = get_map();
9516 if( !!here.veh_at( pos ) ) {
9517 if( const std::optional<vpart_reference> vp = here.veh_at( pos ).part_with_feature( VPFLAG_CARGO,
9518 false ) ) {
9519 vehicle *const veh = &vp->vehicle();
9520 const int cargo = vp->part_index();
9521 vehicle_stack vehicle_items = veh->get_items( cargo );
9522 warm( vehicle_items );
9523 }
9524 return item_warmth;
9525 }
9526 map_stack floor_items = here.i_at( pos );
9527 warm( floor_items );
9528 return item_warmth;
9529}
A vehicle as a whole with all its components.
Definition: vehicle.h:676
vehicle(const vproto_id &type_id, int init_veh_fuel=-1, int init_veh_status=-1)
Definition: vehicle.cpp:252
vehicle_stack get_items(int part) const
Definition: vehicle.cpp:5490
@ VPFLAG_CARGO
Definition: veh_type.h:62

References bp_leg_l, bp_leg_r, bp_torso, vehicle::get_items(), get_map(), map::i_at(), optional_vpart_position::part_with_feature(), pos(), map::veh_at(), vehicle::vehicle(), and VPFLAG_CARGO.

Referenced by floor_warmth().

◆ floor_warmth()

int Character::floor_warmth ( const tripoint pos) const

Final warmth from the floor.

Definition at line 9531 of file character.cpp.

9532{
9533 const int item_warmth = floor_item_warmth( pos );
9534 int bedding_warmth = floor_bedding_warmth( pos );
9535
9536 // If the PC has fur, etc, that will apply too
9537 int floor_mut_warmth = bodytemp_modifier_traits_floor();
9538 // DOWN does not provide floor insulation, though.
9539 // Better-than-light fur or being in one's shell does.
9540 if( ( !( has_trait( trait_DOWN ) ) ) && ( floor_mut_warmth >= 200 ) ) {
9541 bedding_warmth = std::max( 0, bedding_warmth );
9542 }
9543 return ( item_warmth + bedding_warmth + floor_mut_warmth );
9544}
static const trait_id trait_DOWN("DOWN")
static int floor_item_warmth(const tripoint &pos)
Warmth from clothing on the floor.
Definition: character.cpp:9496
int bodytemp_modifier_traits_floor() const
Correction factor of the body temperature due to traits and mutations for player lying on the floor.
Definition: character.cpp:9555

References bodytemp_modifier_traits_floor(), floor_bedding_warmth(), floor_item_warmth(), has_trait(), pos(), and trait_DOWN.

Referenced by update_bodytemp().

◆ footwear_factor()

double Character::footwear_factor ( ) const

Returns 1 if the player is wearing something on both feet, .5 if on one, and 0 if on neither.

Definition at line 8937 of file character.cpp.

8938{
8939 double ret = 0;
8940 if( wearing_something_on( bodypart_id( "foot_l" ) ) ) {
8941 ret += .5;
8942 }
8943 if( wearing_something_on( bodypart_id( "foot_r" ) ) ) {
8944 ret += .5;
8945 }
8946 return ret;
8947}

References cata::hash64_detail::ret, and wearing_something_on().

Referenced by is_immune_effect(), game::knockback(), rooted(), run_cost(), and game::walk_move().

◆ forced_dismount()

void Character::forced_dismount ( )

Definition at line 1087 of file character.cpp.

1088{
1090 bool mech = false;
1091 if( mounted_creature ) {
1092 auto mon = mounted_creature.get();
1093 if( mon->has_flag( MF_RIDEABLE_MECH ) && !mon->type->mech_weapon.is_empty() ) {
1094 mech = true;
1096 }
1097 mon->mounted_player_id = character_id();
1098 mon->remove_effect( effect_ridden );
1099 mon->add_effect( effect_ai_waiting, 5_turns );
1100 mounted_creature = nullptr;
1101 mon->mounted_player = nullptr;
1102 }
1103 std::vector<tripoint> valid;
1104 for( const tripoint &jk : get_map().points_in_radius( pos(), 1 ) ) {
1105 if( g->is_empty( jk ) ) {
1106 valid.push_back( jk );
1107 }
1108 }
1109 if( !valid.empty() ) {
1110 setpos( random_entry( valid ) );
1111 if( mech ) {
1112 add_msg_player_or_npc( m_bad, _( "You are ejected from your mech!" ),
1113 _( "<npcname> is ejected from their mech!" ) );
1114 } else {
1115 add_msg_player_or_npc( m_bad, _( "You fall off your mount!" ),
1116 _( "<npcname> falls off their mount!" ) );
1117 }
1118 const int dodge = get_dodge();
1119 const int damage = std::max( 0, rng( 1, 20 ) - rng( dodge, dodge * 2 ) );
1120 bodypart_id hit( "num_bp" );
1121 switch( rng( 1, 10 ) ) {
1122 case 1:
1123 if( one_in( 2 ) ) {
1124 hit = bodypart_id( "foot_l" );
1125 } else {
1126 hit = bodypart_id( "foot_r" );
1127 }
1128 break;
1129 case 2:
1130 case 3:
1131 case 4:
1132 if( one_in( 2 ) ) {
1133 hit = bodypart_id( "leg_l" );
1134 } else {
1135 hit = bodypart_id( "leg_r" );
1136 }
1137 break;
1138 case 5:
1139 case 6:
1140 case 7:
1141 if( one_in( 2 ) ) {
1142 hit = bodypart_id( "arm_l" );
1143 } else {
1144 hit = bodypart_id( "arm_r" );
1145 }
1146 break;
1147 case 8:
1148 case 9:
1149 hit = bodypart_id( "torso" );
1150 break;
1151 case 10:
1152 hit = bodypart_id( "head" );
1153 break;
1154 }
1155 if( damage > 0 ) {
1156 add_msg_if_player( m_bad, _( "You hurt yourself!" ) );
1157 deal_damage( nullptr, hit, damage_instance( DT_BASH, damage ) );
1158 if( is_avatar() ) {
1159 g->memorial().add(
1160 pgettext( "memorial_male", "Fell off a mount." ),
1161 pgettext( "memorial_female", "Fell off a mount." ) );
1162 }
1164 }
1165 add_effect( effect_downed, 5_turns, num_bp );
1166 } else {
1167 add_msg( m_debug, "Forced_dismount could not find a square to deposit player" );
1168 }
1169 if( is_avatar() ) {
1170 if( g->u.get_grab_type() != OBJECT_NONE ) {
1171 add_msg( m_warning, _( "You let go of the grabbed object." ) );
1172 g->u.grab( OBJECT_NONE );
1173 }
1175 if( g->u.is_auto_moving() || g->u.has_destination() || g->u.has_destination_activity() ) {
1176 g->u.clear_destination();
1177 }
1178 g->update_map( g->u );
1179 }
1180 if( activity ) {
1182 }
1183 moves -= 150;
1184}
static const efftype_id effect_downed("downed")
dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &d) override
Calls Creature::deal_damage and handles damaged effects (waking up, etc.)
Definition: character.cpp:8464
void check_dead_state()
This function checks the creatures is_dead_state and (if true) calls die.
Definition: creature.cpp:1898

References _, Creature::add_msg_player_or_npc(), character_id, effect_ai_waiting, effect_ridden, effect_riding, g, get_map(), m_bad, MF_RIDEABLE_MECH, mounted_creature, points_in_radius(), pos(), primary_weapon(), random_entry(), Creature::remove_effect(), visitable< Character >::remove_item(), and setpos().

Referenced by Creature::add_effect(), check_mount_is_spooked(), monster::die(), and monster::setpos().

◆ fuel_bionic_with()

bool Character::fuel_bionic_with ( item it)

Definition at line 1352 of file consumption.cpp.

1353{
1354 if( !can_fuel_bionic_with( it ) ) {
1355 return false;
1356 }
1357
1359 const std::string str_loaded = get_value( it.typeId().str() );
1360
1361 const int fuel_multiplier = get_bionic_state( bio ).info().fuel_multiplier;
1362
1363 int loadable = std::min( it.charges * fuel_multiplier, get_fuel_capacity( it.typeId() ) );
1364 int loaded = 0;
1365
1366 if( !str_loaded.empty() ) {
1367 loaded = std::stoi( str_loaded );
1368 }
1369
1370 const std::string new_charge = std::to_string( loadable + loaded );
1371
1372 loadable = std::ceil( loadable / fuel_multiplier );
1373 it.charges -= loadable;
1374 // Type and amount of fuel
1375 set_value( it.typeId().str(), new_charge );
1378 //~ %1$i: charge number, %2$s: item name, %3$s: bionics name
1379 vgettext( "You load %1$i charge of %2$s in your %3$s.",
1380 "You load %1$i charges of %2$s in your %3$s.", loadable ),
1381 //~ %1$i: charge number, %2$s: item name, %3$s: bionics name
1382 vgettext( "<npcname> load %1$i charge of %2$s in their %3$s.",
1383 "<npcname> load %1$i charges of %2$s in their %3$s.", loadable ), loadable, it.tname(), bio->name );
1384 mod_moves( -250 );
1385 return true;
1386}
bionic_id get_most_efficient_bionic(const std::vector< bionic_id > &bids) const
Return bionic_id of bionic of most fuel efficient bionic.
Definition: character.cpp:1891
bool can_fuel_bionic_with(const item &it) const
Returns true if the character can fuel a bionic with the item.
Definition: character.cpp:1849
int get_fuel_capacity(const itype_id &fuel) const
Return available space to store specified fuel.
Definition: character.cpp:2034
int fuel_multiplier
Multiplies the amount of fuel when loading into the bionic storage.
Definition: bionics.h:73

References Creature::add_msg_player_or_npc(), can_fuel_bionic_with(), item::charges, bionic_data::fuel_multiplier, get_bionic_fueled_with(), get_bionic_state(), get_fuel_capacity(), get_most_efficient_bionic(), Creature::get_value(), bionic::info(), m_info, Creature::mod_moves(), bionic_data::name, Creature::set_value(), string_id< T >::str(), item::tname(), to_string(), item::typeId(), update_fuel_storage(), and vgettext().

Referenced by consume_item().

◆ fun_for()

std::pair< int, int > Character::fun_for ( const item comest) const

Handles the enjoyability value for a comestible.

First value is enjoyability, second is cap.

Definition at line 472 of file consumption.cpp.

473{
474 if( !comest.is_comestible() ) {
475 return std::pair<int, int>( 0, 0 );
476 }
477
478 // As float to avoid rounding too many times
479 float fun = comest.get_comestible_fun();
480 float fun_max;
481
482 // Lupines/Felines like dog/cat food. Won't skip the rotting check.
483 // This is specifically so that Lupines/Felines don't get the harsher
484 // morale penalties from rotting cat/dog food.
485 if( ( comest.has_flag( flag_LUPINE ) && has_trait( trait_THRESH_LUPINE ) ) ||
486 ( comest.has_flag( flag_FELINE ) && has_trait( trait_THRESH_FELINE ) ) ) {
487 if( fun < 0 ) {
488 fun = -fun / 2;
489 }
490 }
491
492 const float relative_rot = comest.get_relative_rot();
493
494 if( relative_rot > 1.0f && !has_trait( trait_SAPROPHAGE ) && !has_trait( trait_SAPROVORE ) ) {
495 // Rotten food should be pretty disgusting.
496 // Baseline minumum is the same as eating raw meat as a normal human being.
497 fun = std::min( fun - 5, -10.0f );
498 fun_max = fun * 6;
499 } else {
500 // Food is less enjoyable when eaten too often.
501 if( fun > 0 || comest.has_flag( flag_NEGATIVE_MONOTONY_OK ) ) {
502 for( const consumption_event &event : consumption_history->elems ) {
503 if( event.time > calendar::turn - 2_days && event.type_id == comest.typeId() &&
504 event.component_hash == comest.make_component_hash() ) {
505 fun -= comest.get_comestible()->monotony_penalty;
506 // This effect can't drop fun below 0, unless the food has the right flag.
507 // 0 is the lowest we'll go, no need to keep looping.
508 if( fun <= 0 && !comest.has_flag( flag_NEGATIVE_MONOTONY_OK ) ) {
509 fun = 0;
510 break;
511 }
512 }
513 }
514 }
515
516 fun_max = fun < 0 ? fun * 6 : fun * 3;
517
518 // I'd assume since gourmands are just big eaters they still can't stand rotten food.
519 if( has_trait( trait_GOURMAND ) ) {
520 if( fun < -1 ) {
521 fun_max = fun;
522 fun /= 2;
523 } else if( fun > 0 ) {
524 fun_max *= 3;
525 fun = fun * 3 / 2;
526 }
527 }
528 }
529
530 return { static_cast< int >( fun ), static_cast< int >( fun_max ) };
531}
uint64_t make_component_hash() const
Creates a hash from the itype_ids of this item's components.
Definition: item.cpp:8934
int get_comestible_fun() const
Definition: item.cpp:5507
static const std::string flag_NEGATIVE_MONOTONY_OK("NEGATIVE_MONOTONY_OK")
time_point time
Definition: consumption.h:15
uint64_t component_hash
Definition: consumption.h:17
itype_id type_id
Definition: consumption.h:16

References consumption_event::component_hash, consumption_history, flag_FELINE(), flag_LUPINE(), flag_NEGATIVE_MONOTONY_OK(), item::get_comestible(), item::get_comestible_fun(), item::get_relative_rot(), item::has_flag(), has_trait(), item::is_comestible(), item::make_component_hash(), consumption_event::time, trait_GOURMAND, trait_SAPROPHAGE, trait_SAPROVORE, trait_THRESH_FELINE, trait_THRESH_LUPINE, calendar::turn, consumption_event::type_id, and item::typeId().

Referenced by comestible_inventory_preset::comestible_inventory_preset(), find_auto_consume(), item::food_info(), and modify_morale().

◆ get_acquirable_energy() [1/2]

int Character::get_acquirable_energy ( const item it) const

Definition at line 1447 of file consumption.cpp.

1448{
1450}

References get_acquirable_energy(), and get_cbm_rechargeable_with().

◆ get_acquirable_energy() [2/2]

int Character::get_acquirable_energy ( const item it,
rechargeable_cbm  cbm 
) const

Definition at line 1401 of file consumption.cpp.

1402{
1403 switch( cbm ) {
1405 break;
1406
1408 if( it.charges > 0 ) {
1409 const auto iter = plut_charges.find( it.typeId() );
1410 return iter != plut_charges.end() ? it.charges * iter->second : 0;
1411 }
1412
1413 break;
1414
1416 units::volume consumed_vol = it.volume();
1417 units::mass consumed_mass = it.weight();
1419 const double n_stacks = static_cast<double>( it.charges_per_volume( furnace_max_volume ) ) /
1420 it.type->stack_size;
1421 consumed_vol = it.type->volume * n_stacks;
1422 // it.type->weight is in 10g units?
1423 consumed_mass = it.type->weight * 10 * n_stacks;
1424 }
1425 int amount = ( consumed_vol / 250_ml + consumed_mass / 1_gram ) / 9;
1426
1427 // TODO: JSONize.
1428 if( it.made_of( material_id( "leather" ) ) ) {
1429 amount /= 4;
1430 }
1431 if( it.made_of( material_id( "wood" ) ) ) {
1432 amount /= 2;
1433 }
1434
1435 return amount;
1436 }
1439 const int to_consume = std::min( it.charges, bid->fuel_capacity );
1440 const int to_charge = static_cast<int>( it.fuel_energy() * to_consume * bid->fuel_efficiency );
1441 return to_charge;
1442 }
1443
1444 return 0;
1445}
const std::map< itype_id, int > plut_charges
int fuel_capacity
How much fuel this bionic can hold.
Definition: bionics.h:69
units::mass weight
Weight of item ( or each stack member )
Definition: itype.h:933
int stack_size
Number of items per above volume for count_by_charges items.
Definition: itype.h:950
units::volume volume
Space occupied by items of this type CAUTION: value given is for a default-sized stack.
Definition: itype.h:942

References item::charges, item::charges_per_volume(), item::count_by_charges(), bionic_data::fuel_capacity, bionic_data::fuel_efficiency, item::fuel_energy(), furnace, furnace_max_volume, get_bionic_fueled_with(), get_most_efficient_bionic(), item::made_of(), none, other, plut_charges, reactor, itype::stack_size, item::type, item::typeId(), item::volume(), itype::volume, item::weight(), and itype::weight.

Referenced by feed_furnace_with(), and get_acquirable_energy().

◆ get_all_armor_type()

std::map< bodypart_id, int > Character::get_all_armor_type ( damage_type  dt,
const std::map< bodypart_id, std::vector< const item * > > &  clothing_map 
) const

Definition at line 6917 of file character.cpp.

6919{
6920 std::map<bodypart_id, int> ret;
6921 for( const bodypart_id &bp : get_all_body_parts() ) {
6922 ret.emplace( bp, 0 );
6923 }
6924
6925 for( std::pair<const bodypart_id, int> &per_bp : ret ) {
6926 const bodypart_id &bp = per_bp.first;
6927 switch( dt ) {
6928 case DT_TRUE:
6929 case DT_BIOLOGICAL:
6930 // Characters cannot resist this
6931 return ret;
6932 /* BASH, CUT, STAB, and BULLET don't benefit from the clothing_map optimization */
6933 // TODO: Fix that
6934 case DT_BASH:
6935 per_bp.second += get_armor_bash( bp );
6936 break;
6937 case DT_CUT:
6938 per_bp.second += get_armor_cut( bp );
6939 break;
6940 case DT_STAB:
6941 per_bp.second += get_armor_cut( bp ) * 0.8f;
6942 break;
6943 case DT_BULLET:
6944 per_bp.second += get_armor_bullet( bp );
6945 break;
6946 case DT_ACID:
6947 case DT_HEAT:
6948 case DT_COLD:
6949 case DT_ELECTRIC: {
6950 for( const item *it : clothing_map.at( bp ) ) {
6951 per_bp.second += it->damage_resist( dt );
6952 }
6953
6954 per_bp.second += mutation_armor( bp, dt );
6955 break;
6956 }
6957 case DT_NULL:
6958 case NUM_DT:
6959 debugmsg( "Invalid damage type: %d", dt );
6960 return ret;
6961 }
6962 }
6963
6964 return ret;
6965}
int get_armor_cut(bodypart_id bp) const override
Returns overall cutting resistance for the body_part.
Definition: character.cpp:6868
int get_armor_bullet(bodypart_id bp) const override
Returns overall bullet resistance for the body_part.
Definition: character.cpp:6873
int get_armor_bash(bodypart_id bp) const override
Returns overall bashing resistance for the body_part.
Definition: character.cpp:6863
resistances mutation_armor(bodypart_id bp) const
Returns resistances on a body part provided by mutations.
Definition: character.cpp:6427
@ DT_TRUE
Definition: damage.h:22
@ DT_NULL
Definition: damage.h:21
@ NUM_DT
Definition: damage.h:32
@ DT_BIOLOGICAL
Definition: damage.h:23

References debugmsg, DT_ACID, DT_BASH, DT_BIOLOGICAL, DT_BULLET, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_NULL, DT_STAB, DT_TRUE, Creature::get_all_body_parts(), get_armor_bash(), get_armor_bullet(), get_armor_cut(), mutation_armor(), NUM_DT, and cata::hash64_detail::ret.

Referenced by get_armor_fire().

◆ get_all_skills()

const SkillLevelMap & Character::get_all_skills ( ) const

Definition at line 3334 of file character.cpp.

3335{
3336 return *_skills;
3337}

References _skills.

Referenced by player::has_recipe_requirements(), lighting_crafting_speed_multiplier(), set_skills(), and memorial_logger::write().

◆ get_armor_acid()

int Character::get_armor_acid ( bodypart_id  bp) const

Returns overall acid resistance for the body part.

Definition at line 7048 of file character.cpp.

7049{
7050 return get_armor_type( DT_ACID, bp );
7051}
int get_armor_type(damage_type dt, bodypart_id bp) const override
Returns overall resistance to given type on the bod part.
Definition: character.cpp:6879

References DT_ACID, and get_armor_type().

◆ get_armor_bash()

int Character::get_armor_bash ( bodypart_id  bp) const
overridevirtual

Returns overall bashing resistance for the body_part.

Reimplemented from Creature.

Definition at line 6863 of file character.cpp.

6864{
6866}
int get_armor_bash_base(bodypart_id bp) const override
Returns bashing resistance from the creature and armor only.
Definition: character.cpp:6967
int armor_bash_bonus
Definition: creature.h:832

References Creature::armor_bash_bonus, and get_armor_bash_base().

Referenced by get_all_armor_type(), get_armor_type(), game::get_dangerous_tile(), and game::place_player().

◆ get_armor_bash_base()

int Character::get_armor_bash_base ( bodypart_id  bp) const
overridevirtual

Returns bashing resistance from the creature and armor only.

Reimplemented from Creature.

Definition at line 6967 of file character.cpp.

6968{
6969 int ret = 0;
6970 for( auto &i : worn ) {
6971 if( i.covers( bp->token ) ) {
6972 ret += i.bash_resist();
6973 }
6974 }
6975 for( const bionic_id &bid : get_bionics() ) {
6976 const auto bash_prot = bid->bash_protec.find( bp.id() );
6977 if( bash_prot != bid->bash_protec.end() ) {
6978 ret += bash_prot->second;
6979 }
6980 }
6981
6982 ret += mutation_armor( bp, DT_BASH );
6983 return ret;
6984}

References DT_BASH, get_bionics(), int_id< T >::id(), mutation_armor(), cata::hash64_detail::ret, and worn.

Referenced by get_armor_bash().

◆ get_armor_bullet()

int Character::get_armor_bullet ( bodypart_id  bp) const
overridevirtual

Returns overall bullet resistance for the body_part.

Reimplemented from Creature.

Definition at line 6873 of file character.cpp.

6874{
6876}
int get_armor_bullet_base(bodypart_id bp) const override
Returns cutting resistance from the creature and armor only.
Definition: character.cpp:7005
int armor_bullet_bonus
Definition: creature.h:834

References Creature::armor_bullet_bonus, and get_armor_bullet_base().

Referenced by get_all_armor_type(), and get_armor_type().

◆ get_armor_bullet_base()

int Character::get_armor_bullet_base ( bodypart_id  bp) const
overridevirtual

Returns cutting resistance from the creature and armor only.

Reimplemented from Creature.

Definition at line 7005 of file character.cpp.

7006{
7007 int ret = 0;
7008 for( auto &i : worn ) {
7009 if( i.covers( bp->token ) ) {
7010 ret += i.bullet_resist();
7011 }
7012 }
7013
7014 for( const bionic_id &bid : get_bionics() ) {
7015 const auto bullet_prot = bid->bullet_protec.find( bp.id() );
7016 if( bullet_prot != bid->bullet_protec.end() ) {
7017 ret += bullet_prot->second;
7018 }
7019 }
7020
7021 ret += mutation_armor( bp, DT_BULLET );
7022 return ret;
7023}

References DT_BULLET, get_bionics(), int_id< T >::id(), mutation_armor(), cata::hash64_detail::ret, and worn.

Referenced by get_armor_bullet().

◆ get_armor_cut()

int Character::get_armor_cut ( bodypart_id  bp) const
overridevirtual

Returns overall cutting resistance for the body_part.

Reimplemented from Creature.

Definition at line 6868 of file character.cpp.

6869{
6870 return get_armor_cut_base( bp ) + armor_cut_bonus;
6871}
int get_armor_cut_base(bodypart_id bp) const override
Returns cutting resistance from the creature and armor only.
Definition: character.cpp:6986
int armor_cut_bonus
Definition: creature.h:833

References Creature::armor_cut_bonus, and get_armor_cut_base().

Referenced by get_all_armor_type(), get_armor_type(), and map::player_in_field().

◆ get_armor_cut_base()

int Character::get_armor_cut_base ( bodypart_id  bp) const
overridevirtual

Returns cutting resistance from the creature and armor only.

Reimplemented from Creature.

Definition at line 6986 of file character.cpp.

6987{
6988 int ret = 0;
6989 for( auto &i : worn ) {
6990 if( i.covers( bp->token ) ) {
6991 ret += i.cut_resist();
6992 }
6993 }
6994 for( const bionic_id &bid : get_bionics() ) {
6995 const auto cut_prot = bid->cut_protec.find( bp.id() );
6996 if( cut_prot != bid->cut_protec.end() ) {
6997 ret += cut_prot->second;
6998 }
6999 }
7000
7001 ret += mutation_armor( bp, DT_CUT );
7002 return ret;
7003}

References DT_CUT, get_bionics(), int_id< T >::id(), mutation_armor(), cata::hash64_detail::ret, and worn.

Referenced by get_armor_cut().

◆ get_armor_fire()

std::map< bodypart_id, int > Character::get_armor_fire ( const std::map< bodypart_id, std::vector< const item * > > &  clothing_map) const

Returns overall fire resistance.

Definition at line 8250 of file character.cpp.

8252{
8253 return get_all_armor_type( DT_HEAT, clothing_map );
8254}
std::map< bodypart_id, int > get_all_armor_type(damage_type dt, const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
Definition: character.cpp:6917

References DT_HEAT, and get_all_armor_type().

Referenced by update_bodytemp().

◆ get_armor_type()

int Character::get_armor_type ( damage_type  dt,
bodypart_id  bp 
) const
overridevirtual

Returns overall resistance to given type on the bod part.

Implements Creature.

Definition at line 6879 of file character.cpp.

6880{
6881 switch( dt ) {
6882 case DT_TRUE:
6883 case DT_BIOLOGICAL:
6884 return 0;
6885 case DT_BASH:
6886 return get_armor_bash( bp );
6887 case DT_CUT:
6888 return get_armor_cut( bp );
6889 case DT_STAB:
6890 return get_armor_cut( bp ) * 0.8f;
6891 case DT_BULLET:
6892 return get_armor_bullet( bp );
6893 case DT_ACID:
6894 case DT_HEAT:
6895 case DT_COLD:
6896 case DT_ELECTRIC: {
6897 int ret = 0;
6898 for( auto &i : worn ) {
6899 if( i.covers( bp->token ) ) {
6900 ret += i.damage_resist( dt );
6901 }
6902 }
6903
6904 ret += mutation_armor( bp, dt );
6905 return ret;
6906 }
6907 case DT_NULL:
6908 case NUM_DT:
6909 // Let it error below
6910 break;
6911 }
6912
6913 debugmsg( "Invalid damage type: %d", dt );
6914 return 0;
6915}

References debugmsg, DT_ACID, DT_BASH, DT_BIOLOGICAL, DT_BULLET, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_NULL, DT_STAB, DT_TRUE, get_armor_bash(), get_armor_bullet(), get_armor_cut(), mutation_armor(), NUM_DT, cata::hash64_detail::ret, and worn.

Referenced by map::burn_body_part(), get_armor_acid(), and is_immune_field().

◆ get_auto_move_route()

std::vector< tripoint > & Character::get_auto_move_route ( )

Definition at line 10534 of file character.cpp.

10535{
10536 return auto_move_route;
10537}

References auto_move_route.

Referenced by game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), npc::move(), and npc::move_to().

◆ get_base_traits()

std::vector< trait_id > Character::get_base_traits ( ) const

Get the idents of all base traits.

Definition at line 2855 of file newcharacter.cpp.

2856{
2857 return std::vector<trait_id>( my_traits.begin(), my_traits.end() );
2858}

References my_traits.

Referenced by avatar::create(), and set_description().

◆ get_bionic_fueled_with()

std::vector< bionic_id > Character::get_bionic_fueled_with ( const item it) const

Return bionic_id of bionics able to use it as fuel.

Definition at line 1865 of file character.cpp.

1866{
1867 std::vector<bionic_id> bionics;
1868
1869 for( const bionic_id &bid : get_bionics() ) {
1870 for( const itype_id &fuel : bid->fuel_opts ) {
1871 if( fuel == it.typeId() ) {
1872 bionics.emplace_back( bid );
1873 }
1874 }
1875 }
1876
1877 return bionics;
1878}

References get_bionics(), and item::typeId().

Referenced by burn_move_stamina(), fuel_bionic_with(), get_acquirable_energy(), game::on_move_effects(), reset_remote_fuel(), and update_fuel_storage().

◆ get_bionic_state()

bionic & Character::get_bionic_state ( const bionic_id id)

Get state of bionic with given id.

Definition at line 1803 of file character.cpp.

1804{
1805 for( bionic &b : *my_bionics ) {
1806 if( id == b.id ) {
1807 return b;
1808 }
1809 }
1810 debugmsg( "tried to get state of non-existent bionic with id \"%s\"", id );
1811 std::abort();
1812}

References b, debugmsg, and my_bionics.

Referenced by absorb_hit(), npc::activate_bionic_by_id(), npc::check_or_reload_cbm(), npc::deactivate_bionic_by_id(), fuel_bionic_with(), suffer_from_radiation(), and npc::use_bionic_by_id().

◆ get_bionics()

◆ get_cbm_rechargeable_with()

rechargeable_cbm Character::get_cbm_rechargeable_with ( const item it) const

Definition at line 1388 of file consumption.cpp.

1389{
1390 if( can_feed_furnace_with( it ) ) {
1392 }
1393
1394 if( can_fuel_bionic_with( it ) ) {
1396 }
1397
1399}

References can_feed_furnace_with(), can_fuel_bionic_with(), furnace, none, and other.

Referenced by can_consume_for_bionic(), and get_acquirable_energy().

◆ get_check_encumbrance()

bool Character::get_check_encumbrance ( ) const
inline

Definition at line 2020 of file character.h.

2020 {
2021 return check_encumbrance;
2022 }

References check_encumbrance.

Referenced by process_items().

◆ get_consumable_from()

item & Character::get_consumable_from ( item it) const

Returns a reference to the item itself (if it's consumable), the first of its contents (if it's consumable) or null item otherwise.

WARNING: consumable does not necessarily guarantee the comestible type.

Definition at line 1477 of file consumption.cpp.

1478{
1479 if( !it.is_container_empty() && can_consume_as_is( it.contents.front() ) ) {
1480 return it.contents.front();
1481 } else if( can_consume_as_is( it ) ) {
1482 return it;
1483 }
1484
1485 static item null_comestible;
1486 // Since it's not const.
1487 null_comestible = item();
1488 return null_comestible;
1489}

References can_consume_as_is(), item::contents, item_contents::front(), and item::is_container_empty().

Referenced by consume_item(), and find_auto_consume().

◆ get_dependent_worn_items()

std::list< item * > Character::get_dependent_worn_items ( const item it) const

Returns all items that must be taken off before taking off this item.

Definition at line 2425 of file character.cpp.

2426{
2427 std::list<item *> dependent;
2428 // Adds dependent worn items recursively
2429 const std::function<void( const item &it )> add_dependent = [&]( const item & it ) {
2430 for( const item &wit : worn ) {
2431 if( &wit == &it || !wit.is_worn_only_with( it ) ) {
2432 continue;
2433 }
2434 const auto iter = std::find_if( dependent.begin(), dependent.end(),
2435 [&wit]( const item * dit ) {
2436 return &wit == dit;
2437 } );
2438 if( iter == dependent.end() ) { // Not in the list yet
2439 add_dependent( wit );
2440 dependent.push_back( const_cast<item *>( & wit ) );
2441 }
2442 }
2443 };
2444
2445 if( is_worn( it ) ) {
2446 add_dependent( it );
2447 }
2448
2449 return dependent;
2450}

References is_worn(), item::is_worn_only_with(), and worn.

Referenced by can_takeoff(), and pickup::reorder_for_dropping().

◆ get_destination_activity()

player_activity Character::get_destination_activity ( ) const

Definition at line 963 of file character.cpp.

964{
966}

References destination_activity.

Referenced by has_destination_activity(), has_distant_destination(), and start_destination_activity().

◆ get_dex()

◆ get_dex_base()

int Character::get_dex_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4109 of file character.cpp.

4110{
4111 return dex_max;
4112}

References dex_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_dex(), and avatar::get_dex_base().

◆ get_dex_bonus()

int Character::get_dex_bonus ( ) const
virtual

Definition at line 4126 of file character.cpp.

4127{
4128 return dex_bonus;
4129}

References dex_bonus.

Referenced by reset_stats().

◆ get_dodge()

float Character::get_dodge ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 866 of file melee.cpp.

867{
868 //If we're asleep or busy we can't dodge
870 return 0.0f;
871 }
872
873 float ret = Creature::get_dodge();
874 // Chop in half if we are unable to move
877 ret /= 2;
878 }
879
880 if( has_effect( effect_grabbed ) ) {
881 int zed_number = 0;
882 for( auto &dest : g->m.points_in_radius( pos(), 1, 0 ) ) {
883 const monster *const mon = g->critter_at<monster>( dest );
884 if( mon && mon->has_effect( effect_grabbing ) ) {
885 zed_number++;
886 }
887 }
888 ret *= 1.0f - ( 0.25f * zed_number );
889 }
890
891 if( worn_with_flag( "ROLLER_INLINE" ) ||
892 worn_with_flag( "ROLLER_QUAD" ) ||
893 worn_with_flag( "ROLLER_ONE" ) ) {
894 ret /= has_trait( trait_PROF_SKATER ) ? 2 : 5;
895 }
896
898 ret /= 4;
899 }
900
901 // Each dodge after the first subtracts equivalent of 2 points of dodge skill
902 if( dodges_left <= 0 ) {
903 ret += dodges_left * 2 - 2;
904 }
905
906 return std::max( 0.0f, ret );
907}
int dodges_left
Definition: character.h:569
virtual float get_dodge() const
Definition: creature.cpp:1549
static const efftype_id effect_lightsnare("lightsnare")
static const efftype_id effect_grabbing("grabbing")
static const efftype_id effect_bouldering("bouldering")
static const efftype_id effect_beartrap("beartrap")
static const efftype_id effect_grabbed("grabbed")
static const efftype_id effect_heavysnare("heavysnare")
static const trait_id trait_PROF_SKATER("PROF_SKATER")

References dodges_left, effect_beartrap, effect_bouldering, effect_grabbed, effect_grabbing, effect_heavysnare, effect_lightsnare, effect_narcosis, g, Creature::get_dodge(), Creature::has_effect(), has_trait(), in_sleep_state(), pos(), cata::hash64_detail::ret, trait_PROF_SKATER, and worn_with_flag().

Referenced by npc::character_danger(), trapfunc::crossbow(), dodge_roll(), draw_skills_tab(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), mattack::science(), trapfunc::shotgun(), and game::update_stair_monsters().

◆ get_dodge_base()

float Character::get_dodge_base ( ) const
overridevirtual

Combat getters.

Dexterity increases dodge base Dodge increases dodge_base

Implements Creature.

Definition at line 5737 of file character.cpp.

5738{
5739 /** @EFFECT_DEX increases dodge base */
5740 /** @EFFECT_DODGE increases dodge_base */
5741 return get_dex() / 2.0f + get_skill_level( skill_dodge );
5742}

References get_dex(), get_skill_level(), and skill_dodge.

◆ get_effective_efficiency()

float Character::get_effective_efficiency ( bionic bio,
float  fuel_efficiency 
)

Applies modifier to fuel_efficiency and returns the resulting efficiency.

Definition at line 1517 of file bionics.cpp.

1518{
1519 const std::optional<float> &coverage_penalty = bio.info().coverage_power_gen_penalty;
1520 float effective_efficiency = fuel_efficiency;
1521 if( coverage_penalty ) {
1522 int coverage = 0;
1523 const std::map< bodypart_str_id, int > &occupied_bodyparts = bio.info().occupied_bodyparts;
1524 for( const std::pair< const bodypart_str_id, int > &elem : occupied_bodyparts ) {
1525 for( const item &i : worn ) {
1526 if( i.covers( elem.first->token ) && !i.has_flag( flag_ALLOWS_NATURAL_ATTACKS ) &&
1527 !i.has_flag( flag_SEMITANGIBLE ) &&
1528 !i.has_flag( flag_PERSONAL ) && !i.has_flag( flag_AURA ) ) {
1529 coverage += i.get_coverage();
1530 }
1531 }
1532 }
1533 effective_efficiency = fuel_efficiency * ( 1.0 - ( coverage / ( 100.0 *
1534 occupied_bodyparts.size() ) )
1535 * coverage_penalty.value() );
1536 }
1537 return effective_efficiency;
1538}
static const std::string flag_SEMITANGIBLE("SEMITANGIBLE")
static const std::string flag_ALLOWS_NATURAL_ATTACKS("ALLOWS_NATURAL_ATTACKS")
static const std::string flag_AURA("AURA")
static const std::string flag_PERSONAL("PERSONAL")
std::optional< float > coverage_power_gen_penalty
Fraction of coverage diminishing fuel_efficiency.
Definition: bionics.h:77

References bionic_data::coverage_power_gen_penalty, flag_ALLOWS_NATURAL_ATTACKS(), flag_AURA(), flag_PERSONAL(), flag_SEMITANGIBLE(), bionic::info(), bionic_data::occupied_bodyparts, and worn.

Referenced by burn_fuel(), and passive_power_gen().

◆ get_encumbrance() [1/2]

char_encumbrance_data Character::get_encumbrance ( ) const

Get encumbrance for all body parts.

Definition at line 3704 of file character.cpp.

3705{
3706 return *encumbrance_cache;
3707}

References encumbrance_cache.

Referenced by item::on_wear(), character_display::print_encumbrance(), and should_combine_bps().

◆ get_encumbrance() [2/2]

char_encumbrance_data Character::get_encumbrance ( const item new_item) const

Get encumbrance for all body parts as if new_item was also worn.

Definition at line 3709 of file character.cpp.

3710{
3711 return calc_encumbrance( new_item );
3712}

References calc_encumbrance().

◆ get_env_resist()

int Character::get_env_resist ( bodypart_id  bp) const
overridevirtual

Returns overall env_resist on a body_part.

Reimplemented from Creature.

Definition at line 7025 of file character.cpp.

7026{
7027 int ret = 0;
7028 for( auto &i : worn ) {
7029 // Head protection works on eyes too (e.g. baseball cap)
7030 if( i.covers( bp->token ) || ( bp == bodypart_id( "eyes" ) && i.covers( bp_head ) ) ) {
7031 ret += i.get_env_resist();
7032 }
7033 }
7034
7035 for( const bionic_id &bid : get_bionics() ) {
7036 const auto EP = bid->env_protec.find( bp.id() );
7037 if( ( !bid->activated || has_active_bionic( bid ) ) && EP != bid->env_protec.end() ) {
7038 ret += EP->second;
7039 }
7040 }
7041
7042 if( bp == bodypart_id( "eyes" ) && has_trait( trait_SEESLEEP ) ) {
7043 ret += 8;
7044 }
7045 return ret;
7046}
static const trait_id trait_SEESLEEP("SEESLEEP")

References bp_head, get_bionics(), has_active_bionic(), has_trait(), int_id< T >::id(), cata::hash64_detail::ret, trait_SEESLEEP, and worn.

Referenced by iexamine::flower_poppy(), is_immune_field(), and map::player_in_field().

◆ get_faction()

virtual faction * Character::get_faction ( ) const
inlinevirtual

Reimplemented in avatar, and npc.

Definition at line 368 of file character.h.

368 {
369 return nullptr;
370 }

Referenced by complete_craft(), npc::consume_food_from_camp(), basecamp::faction_display(), and npc::has_faction_relationship().

◆ get_fatigue()

◆ get_fatigue_description()

std::pair< std::string, nc_color > Character::get_fatigue_description ( ) const

Definition at line 4420 of file character.cpp.

4421{
4422 int fatigue = get_fatigue();
4423 std::string fatigue_string;
4424 nc_color fatigue_color = c_white;
4426 fatigue_color = c_red;
4427 fatigue_string = _( "Exhausted" );
4428 } else if( fatigue > fatigue_levels::dead_tired ) {
4429 fatigue_color = c_light_red;
4430 fatigue_string = _( "Dead Tired" );
4431 } else if( fatigue > fatigue_levels::tired ) {
4432 fatigue_color = c_yellow;
4433 fatigue_string = _( "Tired" );
4434 }
4435 return std::make_pair( fatigue_string, fatigue_color );
4436}

References _, c_light_red, c_red, c_white, c_yellow, dead_tired, exhausted, fatigue, get_fatigue(), and tired.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), spell::energy_cur_string(), npc::faction_display(), and get_consume_needs_hint().

◆ get_free_bionics_slots()

int Character::get_free_bionics_slots ( const bodypart_id bp) const

Definition at line 2598 of file bionics.cpp.

2599{
2601}
int get_total_bionics_slots(const bodypart_id &bp) const
Definition: bionics.cpp:2593
int get_used_bionics_slots(const bodypart_id &bp) const
Definition: bionics.cpp:2565

References get_total_bionics_slots(), and get_used_bionics_slots().

Referenced by bionic_installation_issues(), and show_bionics_ui().

◆ get_fuel_available()

std::vector< itype_id > Character::get_fuel_available ( const bionic_id bio) const

Return list of available fuel for this bionic.

Definition at line 2013 of file character.cpp.

2014{
2015 std::vector<itype_id> stored_fuels;
2016 for( const itype_id &fuel : bio->fuel_opts ) {
2017 const item tmp_fuel( fuel );
2018 if( !get_value( fuel.str() ).empty() || tmp_fuel.has_flag( flag_PERPETUAL ) ) {
2019 stored_fuels.emplace_back( fuel );
2020 }
2021 }
2022 return stored_fuels;
2023}
static const std::string flag_PERPETUAL("PERPETUAL")

References flag_PERPETUAL(), bionic_data::fuel_opts, Creature::get_value(), item::has_flag(), and string_id< T >::str().

Referenced by burn_fuel(), draw_bionics_titlebar(), passive_power_gen(), process_bionic(), and npc::recharge_cbm().

◆ get_fuel_capacity()

int Character::get_fuel_capacity ( const itype_id fuel) const

Return available space to store specified fuel.

Definition at line 2034 of file character.cpp.

2035{
2036 int amount_stored = 0;
2037 if( !get_value( fuel.str() ).empty() ) {
2038 amount_stored = std::stoi( get_value( fuel.str() ) );
2039 }
2040 int capacity = 0;
2041 for( const bionic_id &bid : get_bionics() ) {
2042 for( const itype_id &fl : bid->fuel_opts ) {
2043 if( get_value( bid.str() ).empty() || get_value( bid.str() ) == fl.str() ) {
2044 if( fl == fuel ) {
2045 capacity += bid->fuel_capacity;
2046 }
2047 }
2048 }
2049 }
2050 return capacity - amount_stored;
2051}

References get_bionics(), Creature::get_value(), and string_id< T >::str().

Referenced by fuel_bionic_with().

◆ get_fuel_type_available()

int Character::get_fuel_type_available ( const itype_id fuel) const

Return available space to store specified fuel.

Definition at line 2025 of file character.cpp.

2026{
2027 int amount_stored = 0;
2028 if( !get_value( fuel.str() ).empty() ) {
2029 amount_stored = std::stoi( get_value( fuel.str() ) );
2030 }
2031 return amount_stored;
2032}

References Creature::get_value(), and string_id< T >::str().

Referenced by suffer_from_radiation().

◆ get_fueled_bionics()

std::vector< bionic_id > Character::get_fueled_bionics ( ) const

Return bionic_id of fueled bionics.

Definition at line 1880 of file character.cpp.

1881{
1882 std::vector<bionic_id> bionics;
1883 for( const bionic_id &bid : get_bionics() ) {
1884 if( !bid->fuel_opts.empty() ) {
1885 bionics.emplace_back( bid );
1886 }
1887 }
1888 return bionics;
1889}

References get_bionics().

Referenced by npc::recharge_cbm(), and npc::wants_to_recharge_cbm().

◆ get_grammatical_genders()

std::vector< std::string > Character::get_grammatical_genders ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 6002 of file character.cpp.

6003{
6004 if( male ) {
6005 return { "m" };
6006 } else {
6007 return { "f" };
6008 }
6009}

References male.

Referenced by translate_gendered_line().

◆ get_healthy()

int Character::get_healthy ( ) const
virtual

Getters for health values exclusive to characters.

Definition at line 4165 of file character.cpp.

4166{
4167 return healthy;
4168}

References healthy.

Referenced by debug_menu::character_edit_menu(), eff_fun_fungus(), eff_fun_spores(), expose_to_disease(), hardcoded_effects(), healing_rate(), healing_rate_medicine(), mend(), print_health(), process_one_effect(), and update_health().

◆ get_healthy_mod()

int Character::get_healthy_mod ( ) const
virtual

Definition at line 4169 of file character.cpp.

4170{
4171 return healthy_mod;
4172}

References healthy_mod.

Referenced by debug_menu::character_edit_menu(), process_one_effect(), suffer_from_radiation(), update_health(), and vomit().

◆ get_highest_category()

std::string Character::get_highest_category ( ) const

Returns the highest mutation category.

Returns the mutation category with the highest strength.

Definition at line 7840 of file character.cpp.

7841{
7842 int iLevel = 0;
7843 std::string sMaxCat;
7844
7845 for( const std::pair<const std::string, int> &elem : mutation_category_level ) {
7846 if( elem.second > iLevel ) {
7847 sMaxCat = elem.first;
7848 iLevel = elem.second;
7849 } else if( elem.second == iLevel ) {
7850 sMaxCat.clear(); // no category on ties
7851 }
7852 }
7853 return sMaxCat;
7854}
std::map< std::string, int > mutation_category_level
Definition: character.h:1781

References mutation_category_level.

Referenced by hardcoded_effects(), old_mutate(), map::player_in_field(), and test_crossing_threshold().

◆ get_hit_base()

float Character::get_hit_base ( ) const
overridevirtual
Dexterity increases hit base, slightly

Implements Creature.

Definition at line 5743 of file character.cpp.

5744{
5745 /** @EFFECT_DEX increases hit base, slightly */
5746 return get_dex() / 4.0f;
5747}

References get_dex().

Referenced by get_melee_hit_base().

◆ get_hit_weapon()

float Character::get_hit_weapon ( const item weap) const

Gets melee accuracy component from weapon+skills.

Unarmed improves hit chance for unarmed weapons Bashing improves hit chance for bashing weapons Cutting improves hit chance for cutting weapons Stabbing improves hit chance for piercing weapons Melee improves hit chance for all items (including non-weapons)

Definition at line 334 of file melee.cpp.

335{
336 /** @EFFECT_UNARMED improves hit chance for unarmed weapons */
337 /** @EFFECT_BASHING improves hit chance for bashing weapons */
338 /** @EFFECT_CUTTING improves hit chance for cutting weapons */
339 /** @EFFECT_STABBING improves hit chance for piercing weapons */
340 auto skill = get_skill_level( weap.melee_skill() );
341
342 // CQB bionic acts as a lower bound providing item uses a weapon skill
343 if( skill < BIO_CQB_LEVEL && has_active_bionic( bio_cqb ) ) {
344 skill = BIO_CQB_LEVEL;
345 }
346
347 /** @EFFECT_MELEE improves hit chance for all items (including non-weapons) */
348 return ( skill / 3.0f ) + ( get_skill_level( skill_melee ) / 2.0f ) + weap.type->m_to_hit;
349}

References bio_cqb, BIO_CQB_LEVEL, get_skill_level(), has_active_bionic(), itype::m_to_hit, item::melee_skill(), skill_melee, and item::type.

Referenced by item::effective_dps(), and get_melee_hit_base().

◆ get_hostile_creatures()

std::vector< Creature * > Character::get_hostile_creatures ( int  range) const

Get all hostile creatures currently visible to this player.

Definition at line 10237 of file character.cpp.

10238{
10239 return g->get_creatures_if( [this, range]( const Creature & critter ) -> bool {
10240 // Fixes circular distance range for ranged attacks
10241 float dist_to_creature = std::round( rl_dist_exact( pos(), critter.pos() ) );
10242 return this != &critter && pos() != critter.pos() && // TODO: get rid of fake npcs (pos() check)
10243 dist_to_creature <= range && critter.attitude_to( *this ) == A_HOSTILE
10244 && sees( critter );
10245 } );
10246}
@ range
Definition: character.h:104
virtual Attitude attitude_to(const Creature &other) const =0
Attitude (of this creature) towards another creature.
float rl_dist_exact(const tripoint &loc1, const tripoint &loc2)
Definition: line.cpp:292

References Creature::A_HOSTILE, Creature::attitude_to(), g, Creature::pos(), pos(), range, rl_dist_exact(), and sees().

◆ get_hunger_description()

std::pair< std::string, nc_color > Character::get_hunger_description ( ) const

Definition at line 4385 of file character.cpp.

4386{
4387 int total_kcal = stored_calories + stomach.get_calories();
4388 int max_kcal = max_stored_kcal();
4389 float days_left = static_cast<float>( total_kcal ) / bmr();
4390 float days_max = static_cast<float>( max_kcal ) / bmr();
4391 std::string hunger_string;
4392 nc_color hunger_color = c_white;
4393 if( days_left >= days_max ) {
4394 hunger_string = _( "Engorged" );
4395 hunger_color = c_green;
4396 } else if( days_max - days_left < 0.5f ) {
4397 hunger_string = _( "Sated" );
4398 hunger_color = c_green;
4399 } else if( days_max - days_left < 1.0f ) {
4400 hunger_string = _( "Hungry" );
4401 hunger_color = c_yellow;
4402 } else if( days_max / days_left < 2.0f ) {
4403 hunger_string = _( "Very Hungry" );
4404 hunger_color = c_yellow;
4405 } else if( days_left > 1 ) {
4406 hunger_string = _( "Famished" );
4407 hunger_color = c_light_red;
4408 } else {
4409 hunger_string = _( "Starving" );
4410 hunger_color = c_red;
4411 }
4412
4413 if( has_trait( trait_SELFAWARE ) ) {
4414 hunger_string = string_format( "%d kcal", total_kcal );
4415 }
4416
4417 return std::make_pair( hunger_string, hunger_color );
4418}
static const trait_id trait_SELFAWARE("SELFAWARE")

References _, bmr(), c_green, c_light_red, c_red, c_white, c_yellow, stomach_contents::get_calories(), has_trait(), max_stored_kcal(), stomach, stored_calories, string_format(), and trait_SELFAWARE.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), npc::faction_display(), and get_consume_needs_hint().

◆ get_int()

◆ get_int_base()

int Character::get_int_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4117 of file character.cpp.

4118{
4119 return int_max;
4120}

References int_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_int(), and avatar::get_int_base().

◆ get_int_bonus()

int Character::get_int_bonus ( ) const
virtual

Definition at line 4134 of file character.cpp.

4135{
4136 return int_bonus;
4137}

References int_bonus.

Referenced by reset_stats().

◆ get_item_position()

int Character::get_item_position ( const item it) const

Returns the item position (suitable for i_at or similar) of a specific item.

Returns INT_MIN if the item is not found. Note that this may lose some information, for example the returned position is the same when the given item points to the container and when it points to the item inside the container. All items that are part of the same stack have the same item position.

Definition at line 2354 of file character.cpp.

2355{
2356 const item &weapon = primary_weapon();
2357 if( weapon.has_item( *it ) ) {
2358 return -1;
2359 }
2360
2361 int p = 0;
2362 for( const auto &e : worn ) {
2363 if( e.has_item( *it ) ) {
2364 return worn_position_to_index( p );
2365 }
2366 p++;
2367 }
2368
2369 return inv.position_by_item( it );
2370}
static int worn_position_to_index(int position)
Definition: character.h:1094
bool has_item(const item &it) const
Returns true if this visitable instance contains the item.
Definition: visitable.cpp:95

References visitable< T >::has_item(), inv, inventory::position_by_item(), primary_weapon(), worn, and worn_position_to_index().

Referenced by npc::alt_attack(), game::butcher(), iuse::chop_logs(), iuse::chop_tree(), chop_tree_activity(), convert_to_items(), damage_item(), iuse::fill_pit(), iuse::hacksaw(), monexamine::insert_battery(), iuse::makemound(), item_location::impl::item_on_person::obtain(), iuse::pack_item(), iuse::play_game(), iuse::radglove(), iuse::stimpack(), salvage_actor::try_to_cut_up(), pick_lock_actor::use(), musical_instrument_actor::use(), repair_item_actor::use(), sew_advanced_actor::use(), and avatar_action::wield().

◆ get_kcal_percent()

◆ get_learned_recipes()

const recipe_subset & Character::get_learned_recipes ( ) const

Returns all known recipes.

Definition at line 10582 of file character.cpp.

10583{
10584 if( *_skills != *autolearn_skills_stamp ) {
10585 for( const auto &r : recipe_dict.all_autolearn() ) {
10586 if( meets_skill_requirements( r->autolearn_requirements ) ) {
10587 learned_recipes->include( r );
10588 }
10589 }
10591 }
10592
10593 return *learned_recipes;
10594}
pimpl< recipe_subset > learned_recipes
Subset of learned recipes.
Definition: character.h:2179
pimpl< SkillLevelMap > autolearn_skills_stamp
Stamp of character skills.
Definition: character.h:2177
const std::set< const recipe * > & all_autolearn() const
Returns all recipes that can be automatically learned.

References _skills, recipe_dictionary::all_autolearn(), autolearn_skills_stamp, learned_recipes, meets_skill_requirements(), and recipe_dict.

Referenced by player::get_available_recipes(), knows_recipe(), peek_related_recipe(), and select_crafting_recipe().

◆ get_lowest_hp()

int Character::get_lowest_hp ( ) const

Definition at line 10376 of file character.cpp.

10377{
10378 // Set lowest_hp to an arbitrarily large number.
10379 int lowest_hp = 999;
10380 for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
10381 const int cur_hp = elem.second.get_hp_cur();
10382 if( cur_hp < lowest_hp ) {
10383 lowest_hp = cur_hp;
10384 }
10385 }
10386 return lowest_hp;
10387}

References Creature::get_body().

Referenced by debug_menu::character_edit_menu().

◆ get_max_healthy()

int Character::get_max_healthy ( ) const

Definition at line 4567 of file character.cpp.

4568{
4569 return 200;
4570}

Referenced by update_health().

◆ get_max_power_level()

◆ get_melee()

float Character::get_melee ( ) const
overridevirtual

Returns melee skill level, to be used to throttle dodge practice.

Implements Creature.

Definition at line 914 of file melee.cpp.

915{
916 return get_skill_level( skill_id( "melee" ) );
917}

References get_skill_level(), and skill_id.

Referenced by stability_roll().

◆ get_melee_hit_base()

float Character::get_melee_hit_base ( ) const

Returns weapon skill.

Definition at line 351 of file melee.cpp.

352{
353 // Character::get_hit_base includes stat calculations already
355}
item & used_weapon()
Legacy code hack, don't use.
Definition: melee.cpp:144
float get_hit_weapon(const item &weap) const
Gets melee accuracy component from weapon+skills.
Definition: melee.cpp:334
float get_hit_base() const override
Definition: character.cpp:5743
float mabuff_tohit_bonus() const
Returns the to hit bonus from martial arts buffs.

References get_hit_base(), get_hit_weapon(), mabuff_tohit_bonus(), and used_weapon().

Referenced by draw_stats_info(), hit_roll(), and set_stats().

◆ get_miss_reason()

std::string Character::get_miss_reason ( )

Returns an explanation for why the player would miss a melee attack.

Definition at line 389 of file melee.cpp.

390{
391 // everything that lowers accuracy in player::hit_roll()
392 // adding it in hit_roll() might not be safe if it's called multiple times
393 // in one turn
395 _( "Your torso encumbrance throws you off-balance." ),
396 roll_remainder( encumb( bp_torso ) / 10.0 ) );
397 const int farsightedness = 2 * ( has_trait( trait_HYPEROPIC ) &&
398 !worn_with_flag( "FIX_FARSIGHT" ) &&
401 _( "You can't hit reliably due to your farsightedness." ),
402 farsightedness );
403
404 const std::string *const reason = melee_miss_reasons.pick();
405 if( reason == nullptr ) {
406 return std::string();
407 }
408 return *reason;
409}
void add_miss_reason(const std::string &reason, unsigned int weight)
Adds a reason for why the player would miss a melee attack.
Definition: melee.cpp:378
static const efftype_id effect_contacts("contacts")
static const trait_id trait_HYPEROPIC("HYPEROPIC")

References _, add_miss_reason(), bp_torso, effect_contacts, encumb(), Creature::has_effect(), has_trait(), melee_miss_reasons, roll_remainder(), trait_HYPEROPIC, and worn_with_flag().

Referenced by melee_attack().

◆ get_mod()

int Character::get_mod ( const trait_id mut,
const std::string &  arg 
) const
private

Retrieves a stat mod of a mutation.

Definition at line 193 of file mutation.cpp.

194{
195 auto &mod_data = mut->mods;
196 int ret = 0;
197 auto found = mod_data.find( std::make_pair( false, arg ) );
198 if( found != mod_data.end() ) {
199 ret += found->second;
200 }
201 return ret;
202}
detail::named_arg< Char, T > arg(const Char *name, const T &arg)
\rst Returns a named argument to be used in a formatting function.
Definition: fmtlib_core.h:1860
std::unordered_map< std::pair< bool, std::string >, int, cata::tuple_hash > mods
Key pair is <active: bool, mod type: "STR">
Definition: mutation.h:275

References arg(), mutation_branch::mods, and cata::hash64_detail::ret.

Referenced by apply_mods().

◆ get_mod_stat_from_bionic()

int Character::get_mod_stat_from_bionic ( const character_stat Stat) const

Get stat bonus from bionic.

Definition at line 2115 of file character.cpp.

2116{
2117 int ret = 0;
2118 for( const bionic_id &bid : get_bionics() ) {
2119 const auto St_bn = bid->stat_bonus.find( Stat );
2120 if( St_bn != bid->stat_bonus.end() ) {
2121 ret += St_bn->second;
2122 }
2123 }
2124 return ret;
2125}

References get_bionics(), and cata::hash64_detail::ret.

Referenced by reset_stats().

◆ get_morale()

int Character::get_morale ( const morale_type type) const

Definition at line 9109 of file character.cpp.

9110{
9111 return morale->get( type );
9112}

References morale, and type.

◆ get_morale_level()

int Character::get_morale_level ( ) const

◆ get_most_efficient_bionic()

bionic_id Character::get_most_efficient_bionic ( const std::vector< bionic_id > &  bids) const

Return bionic_id of bionic of most fuel efficient bionic.

Definition at line 1891 of file character.cpp.

1892{
1893 float temp_eff = 0;
1894 bionic_id bio( "null" );
1895 for( const bionic_id &bid : bids ) {
1896 if( bid->fuel_efficiency > temp_eff ) {
1897 temp_eff = bid->fuel_efficiency;
1898 bio = bid;
1899 }
1900 }
1901 return bio;
1902}

Referenced by fuel_bionic_with(), and get_acquirable_energy().

◆ get_movement_mode()

character_movemode Character::get_movement_mode ( ) const

Definition at line 1554 of file character.cpp.

1555{
1556 return move_mode;
1557}

References move_mode.

Referenced by cata_event_dispatch::avatar_moves().

◆ get_mutation_social_mods()

social_modifiers Character::get_mutation_social_mods ( ) const

Goes over all mutations, returning the sum of the social modifiers.

Definition at line 6560 of file character.cpp.

6561{
6562 social_modifiers mods;
6563 for( const mutation_branch *mut : cached_mutations ) {
6564 mods += mut->social_mods;
6565 }
6566
6567 return mods;
6568}

References cached_mutations.

Referenced by talk_trial::calc_chance().

◆ get_mutations()

std::vector< trait_id > Character::get_mutations ( bool  include_hidden = true) const

Get the idents of all traits/mutations.

Definition at line 2860 of file newcharacter.cpp.

2861{
2862 std::vector<trait_id> result;
2863 for( const std::pair<const trait_id, char_trait_data> &t : my_mutations ) {
2864 if( include_hidden || t.first.obj().player_display ) {
2865 result.push_back( t.first );
2866 }
2867 }
2868 for( const trait_id &ench_trait : enchantment_cache->get_mutations() ) {
2869 if( include_hidden || ench_trait->player_display ) {
2870 bool found = false;
2871 for( const trait_id &exist : result ) {
2872 if( exist == ench_trait ) {
2873 found = true;
2874 break;
2875 }
2876 }
2877 if( !found ) {
2878 result.push_back( ench_trait );
2879 }
2880 }
2881 }
2882 return result;
2883}

References enchantment_cache, and my_mutations.

Referenced by monster::attitude(), bodytemp_modifier_traits(), bodytemp_modifier_traits_floor(), can_eat(), can_install_cbm_on_bp(), can_use_heal_item(), can_wear(), check_and_recover_morale(), compute_default_effective_vitamins(), player::crafting_success_roll(), avatar::create(), crossed_threshold(), character_display::disp_info(), drench_mut_calc(), npc::form_opinion(), has_trait_flag(), is_category_allowed(), is_weak_to_water(), mod_healthy(), mut_cbm_encumb(), mutation_armor(), mutation_attacks(), item::mutations_from_wearing(), diary::new_page(), process_turn(), avatar::randomize(), reset_scenario(), roll_bash_damage(), roll_cut_damage(), roll_stab_damage(), set_description(), set_highest_cat_level(), set_profession(), sleep(), update_type_of_scent(), visible_mutations(), vitamin_rate(), and memorial_logger::write().

◆ get_name()

std::string Character::get_name ( ) const
overridevirtual

Implements Creature.

Definition at line 5997 of file character.cpp.

5998{
5999 return name;
6000}

References name.

Referenced by apply_damage(), autodoc_internal(), npc::die(), pour_into(), npc::set_omt_destination(), and game::vertical_move().

◆ get_next_auto_move_direction()

action_id Character::get_next_auto_move_direction ( )

Definition at line 10539 of file character.cpp.

10540{
10541 if( !has_destination() ) {
10542 return ACTION_NULL;
10543 }
10544
10546 if( pos() != *next_expected_position ) {
10547 // We're off course, possibly stumbling or stuck, cancel auto move
10548 return ACTION_NULL;
10549 }
10550 }
10551
10552 next_expected_position.emplace( auto_move_route.front() );
10553 auto_move_route.erase( auto_move_route.begin() );
10554
10556
10557 // Make sure the direction is just one step and that
10558 // all diagonal moves have 0 z component
10559 if( std::abs( dp.x ) > 1 || std::abs( dp.y ) > 1 || std::abs( dp.z ) > 1 ||
10560 ( std::abs( dp.z ) != 0 && ( std::abs( dp.x ) != 0 || std::abs( dp.y ) != 0 ) ) ) {
10561 // Should never happen, but check just in case
10562 return ACTION_NULL;
10563 }
10565}
action_id get_movement_action_from_delta(const tripoint &d, const iso_rotate rot)
Translate coordinate delta into movement action.
Definition: action.cpp:485
@ ACTION_NULL
Invalid action used for various lookup errors.
Definition: action.h:20
int y
Definition: point.h:137
int z
Definition: point.h:138
int x
Definition: point.h:136

References ACTION_NULL, auto_move_route, get_movement_action_from_delta(), has_destination(), next_expected_position, pos(), tripoint::x, tripoint::y, yes, and tripoint::z.

Referenced by game::handle_action(), and game::try_get_left_click_action().

◆ get_npc_ai_info_cache()

std::optional< double > Character::get_npc_ai_info_cache ( npc_ai_info  key) const

Definition at line 10639 of file character.cpp.

10640{
10641 return npc_ai_info_cache[key];
10642}

References npc_ai_info_cache.

Referenced by npc::check_or_reload_cbm(), npc::find_reloadable(), npc::wield_better_weapon(), and npc_ai::wielded_value().

◆ get_overlay_ids()

std::vector< std::string > Character::get_overlay_ids ( ) const

Returns a list of the IDs of overlays on this character, sorted from "lowest" to "highest".

Only required for rendering.

Definition at line 3283 of file character.cpp.

3284{
3285 std::vector<std::string> rval;
3286 std::multimap<int, std::string> mutation_sorting;
3287 int order;
3288 std::string overlay_id;
3289
3290 // first get effects
3291 for( const auto &eff_pr : *effects ) {
3292 if( !eff_pr.second.begin()->second.is_removed() ) {
3293 rval.emplace_back( "effect_" + eff_pr.first.str() );
3294 }
3295 }
3296
3297 // then get mutations
3298 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
3299 overlay_id = ( mut.second.powered ? "active_" : "" ) + mut.first.str();
3300 order = get_overlay_order_of_mutation( overlay_id );
3301 mutation_sorting.insert( std::pair<int, std::string>( order, overlay_id ) );
3302 }
3303
3304 // then get bionics
3305 for( const bionic &bio : *my_bionics ) {
3306 overlay_id = ( bio.powered ? "active_" : "" ) + bio.id.str();
3307 order = get_overlay_order_of_mutation( overlay_id );
3308 mutation_sorting.insert( std::pair<int, std::string>( order, overlay_id ) );
3309 }
3310
3311 for( auto &mutorder : mutation_sorting ) {
3312 rval.push_back( "mutation_" + mutorder.second );
3313 }
3314
3315 // next clothing
3316 // TODO: worry about correct order of clothing overlays
3317 for( const item &worn_item : worn ) {
3318 rval.push_back( "worn_" + worn_item.typeId().str() );
3319 }
3320
3321 // last weapon
3322 // TODO: might there be clothing that covers the weapon?
3323 const item &weapon = primary_weapon();
3324 if( is_armed() ) {
3325 rval.push_back( "wielded_" + weapon.typeId().str() );
3326 }
3327
3328 if( move_mode != CMM_WALK ) {
3329 rval.push_back( io::enum_to_string( move_mode ) );
3330 }
3331 return rval;
3332}
std::string enum_to_string(E)
int get_overlay_order_of_mutation(const std::string &mutation_id_string)

References CMM_WALK, Creature::effects, io::enum_to_string(), get_overlay_order_of_mutation(), is_armed(), move_mode, my_bionics, my_mutations, primary_weapon(), string_id< T >::str(), item::typeId(), and worn.

◆ get_pain_description()

std::pair< std::string, nc_color > Character::get_pain_description ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 4489 of file character.cpp.

4490{
4491 const std::pair<std::string, nc_color> pain = Creature::get_pain_description();
4492 nc_color pain_color = pain.second;
4493 std::string pain_string;
4494 // get pain color
4495 if( get_perceived_pain() >= 60 ) {
4496 pain_color = c_red;
4497 } else if( get_perceived_pain() >= 40 ) {
4498 pain_color = c_light_red;
4499 }
4500 // get pain string
4502 get_perceived_pain() > 0 ) {
4503 pain_string = string_format( "%s %d", _( "Pain " ), get_perceived_pain() );
4504 } else if( get_perceived_pain() > 0 ) {
4505 pain_string = pain.first;
4506 }
4507 return std::make_pair( pain_string, pain_color );
4508}
static const efftype_id effect_got_checked("got_checked")
virtual std::pair< std::string, nc_color > get_pain_description() const
Definition: creature.cpp:1416
int pain
Definition: creature.h:901

References _, c_light_red, c_red, effect_got_checked, Creature::get_pain_description(), get_perceived_pain(), Creature::has_effect(), has_trait(), Creature::pain, string_format(), and trait_SELFAWARE.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), and get_consume_needs_hint().

◆ get_painkiller()

int Character::get_painkiller ( ) const

◆ get_path_avoid()

std::set< tripoint > Character::get_path_avoid ( ) const
overridevirtual

Returns a set of points we do not want to path through.

Implements Creature.

Reimplemented in npc.

Definition at line 9956 of file character.cpp.

9957{
9958 std::set<tripoint> ret;
9959 for( npc &guy : g->all_npcs() ) {
9960 if( sees( guy ) ) {
9961 ret.insert( guy.pos() );
9962 }
9963 }
9964
9965 // TODO: Add known traps in a way that doesn't destroy performance
9966
9967 return ret;
9968}

References g, cata::hash64_detail::ret, and sees().

Referenced by activity_on_turn_move_loot(), can_mount(), game::handle_action(), game::list_items(), game::look_around(), perform_zone_activity_turn(), route_adjacent(), activity_handlers::travel_do_turn(), and game::try_get_left_click_action().

◆ get_pathfinding_settings()

const pathfinding_settings & Character::get_pathfinding_settings ( ) const
overridevirtual

◆ get_per()

◆ get_per_base()

int Character::get_per_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4113 of file character.cpp.

4114{
4115 return per_max;
4116}

References per_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_per(), and avatar::get_per_base().

◆ get_per_bonus()

int Character::get_per_bonus ( ) const
virtual

Definition at line 4130 of file character.cpp.

4131{
4132 return per_bonus;
4133}

References per_bonus.

Referenced by reset_stats().

◆ get_perceived_pain()

int Character::get_perceived_pain ( ) const
overridevirtual

◆ get_power_level()

◆ get_rad()

◆ get_remote_fueled_bionic()

bionic_id Character::get_remote_fueled_bionic ( ) const

Returns bionic_id of first remote fueled bionic found.

Definition at line 1839 of file character.cpp.

1840{
1841 for( const bionic_id &bid : get_bionics() ) {
1842 if( bid->is_remote_fueled ) {
1843 return bid;
1844 }
1845 }
1846 return bionic_id();
1847}

References bionic_id, and get_bionics().

Referenced by iuse::cable_attach(), and iuse::solarpack().

◆ get_safe_reference()

safe_reference< Character > Character::get_safe_reference ( )

Definition at line 11059 of file character.cpp.

11060{
11061 return anchor.reference_to( this );
11062}
safe_reference_anchor anchor
Definition: character.h:2281
safe_reference< T > reference_to(T *object)

References anchor, and safe_reference_anchor::reference_to().

Referenced by itype::invoke().

◆ get_shout_volume()

int Character::get_shout_volume ( ) const
Strength increases shouting volume

Definition at line 7589 of file character.cpp.

7590{
7591 int base = 10;
7592 int shout_multiplier = 2;
7593
7594 // Mutations make shouting louder, they also define the default message
7595 if( has_trait( trait_SHOUT3 ) ) {
7596 shout_multiplier = 4;
7597 base = 20;
7598 } else if( has_trait( trait_SHOUT2 ) ) {
7599 base = 15;
7600 shout_multiplier = 3;
7601 }
7602
7603 // You can't shout without your face
7604 if( has_trait( trait_PROF_FOODP ) && !( is_wearing( itype_id( "foodperson_mask" ) ) ||
7605 is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) {
7606 base = 0;
7607 shout_multiplier = 0;
7608 }
7609
7610 // Masks and such dampen the sound
7611 // Balanced around whisper for wearing bondage mask
7612 // and noise ~= 10 (door smashing) for wearing dust mask for character with strength = 8
7613 /** @EFFECT_STR increases shouting volume */
7614 const int penalty = encumb( bp_mouth ) * 3 / 2;
7615 int noise = base + str_cur * shout_multiplier - penalty;
7616
7617 // Minimum noise volume possible after all reductions.
7618 // Volume 1 can't be heard even by player
7619 constexpr int minimum_noise = 2;
7620
7621 if( noise <= base ) {
7622 noise = std::max( minimum_noise, noise );
7623 }
7624
7625 // Screaming underwater is not good for oxygen and harder to do overall
7626 if( is_underwater() ) {
7627 noise = std::max( minimum_noise, noise / 2 );
7628 }
7629 return noise;
7630}
static const trait_id trait_SHOUT2("SHOUT2")
static const trait_id trait_SHOUT3("SHOUT3")

References bp_mouth, encumb(), has_trait(), Creature::is_underwater(), is_wearing(), itype_id, noise, str_cur, trait_PROF_FOODP, trait_SHOUT2, and trait_SHOUT3.

Referenced by game::chat(), npc::say(), shout(), and activity_handlers::spellcasting_finish().

◆ get_size()

◆ get_skill_level() [1/2]

int Character::get_skill_level ( const skill_id ident) const

Definition at line 3349 of file character.cpp.

3350{
3351 return _skills->get_skill_level( ident );
3352}

References _skills.

Referenced by npc::address_needs(), ranged::aim_speed_skill_modifier(), apply_skill_boost(), iexamine::arcfurnace_empty(), attack_cost(), avoid_trap(), mattack::bio_op_disarm(), bionics_pl_skill(), block_hit(), item::book_info(), ranged::burst_penalty(), activity_handlers::butcher_finish(), calc_skill_training_cost(), calc_skill_training_time(), veh_utils::calc_xp_gain(), character_martial_arts::can_arm_block(), can_autolearn_martial_art(), can_estimate_rot(), character_martial_arts::can_leg_block(), can_mount(), npc::can_read(), enzlave_actor::can_use(), caravan_price(), activity_handlers::chop_planks_finish(), item::color_in_inventory(), companion_combat_rank(), companion_industry_rank(), companion_survival_rank(), complete_craft(), crafting::complete_disassemble(), construction_color(), player::crafting_success_roll(), crit_chance(), iuse::crowbar(), salvage_actor::cut_up(), mattack::dermatik(), trap::detect_trap(), avatar::do_read(), dialogue::dynamic_line(), iuse::einktabletpc(), enumerate_unmet_requirements(), spell::exp_modifier(), map_data_common_t::extended_description(), npc::faction_display(), fall_damage_mod(), farm_action(), game::find_or_make_stairs(), npc::finish_read(), activity_handlers::fish_do_turn(), iuse::fish_trap(), item::food_info(), fungal_effects::fungalize(), player::get_available_recipes(), item::get_available_recipes(), heal_actor::get_bandaged_level(), avatar::get_book_reader(), heal_actor::get_disinfected_level(), get_dodge_base(), get_encumbrance_description(), heal_actor::get_heal_value(), get_hit_weapon(), get_melee(), player_activity::get_progress_message(), ranged::get_weapon_dispersion(), iuse::gun_repair(), avatar_funcs::gunmod_installation_odds(), computer_session::hack_attempt(), hack_level(), hackveh(), handle_melee_wear(), hardcoded_mutation_attack(), harvest_common(), iexamine::harvest_plant(), has_skill_for_vehicle_work(), ma_requirements::is_valid_character(), item_reload_cost(), item_store_cost(), ma_style_callback::key(), iexamine::kiln_empty(), activity_handlers::lockpicking_finish(), melee_attack(), avatar_funcs::mend_item(), iuse::mind_splicer(), morale_crafting_speed_multiplier(), iuse::multicooker(), mutation_attacks(), npc_trading::net_price_adjustment(), game::npc_menu(), on_dodge(), item::on_wield(), iuse::pack_cbm(), monexamine::pet_menu(), pick_part_to_heal(), pick_plant(), vehicle::pldrive(), practice(), iexamine::practice_survival_while_foraging(), mattack::pull_metal_weapon(), activity_handlers::pulp_do_turn(), avatar::randomize(), examine_item_menu::rate_action_use(), reach_attack(), avatar::read(), recalc_hp(), repair_item_actor::repair(), repair_item_actor::repair_chance(), activity_handlers::repair_item_finish(), activity_handlers::robot_control_finish(), iuse::robotcontrol(), roll_bash_damage(), roll_cut_damage(), roll_stab_damage(), iexamine::safe(), scavenging_combat_skill(), set_description(), conditional_t< T >::set_has_skill(), set_skills(), map::shake_vehicle(), iexamine::shrub_wildveggies(), sinkhole_safety_roll(), skill_increment_cost(), skill_req_completed(), achievement::skill_ui_text(), npc::skills_offered_to(), smash(), read_inventory_preset::sort_compare(), spell::spell_fail(), player::start_craft(), talk_function::start_training(), suffer_from_schizophrenia(), survive_random_encounter(), swim_speed(), character_effects::talk_skill(), iuse::tazer(), ranged::throw_item(), throw_range(), mattack::thrown_by_judo(), ranged::time_to_attack(), known_magic::time_to_learn_spell(), npc::time_to_read(), avatar::time_to_read(), item::tname(), activity_handlers::train_finish(), iexamine::tree_hickory(), avatar_funcs::try_disarm_npc(), character_funcs::try_wield_contents(), veh_interact::update_part_requirements(), place_monster_iuse::use(), firestarter_actor::use(), enzlave_actor::use(), heal_actor::use(), sew_advanced_actor::use(), npc::value(), game::vertical_move(), and debug_menu::wishskill().

◆ get_skill_level() [2/2]

int Character::get_skill_level ( const skill_id ident,
const item context 
) const

Definition at line 3354 of file character.cpp.

3355{
3356 return _skills->get_skill_level( ident, context );
3357}

References _skills.

◆ get_skill_level_object() [1/2]

◆ get_skill_level_object() [2/2]

const SkillLevel & Character::get_skill_level_object ( const skill_id ident) const

Definition at line 3339 of file character.cpp.

3340{
3341 return _skills->get_skill_level_object( ident );
3342}

References _skills.

◆ get_sleep_deprivation()

int Character::get_sleep_deprivation ( ) const

Definition at line 4484 of file character.cpp.

4485{
4486 return sleep_deprivation;
4487}

References sleep_deprivation.

Referenced by debug_menu::character_edit_menu(), check_needs_extremes(), hardcoded_effects(), reset_stats(), and suffer().

◆ get_speed()

◆ get_stamina()

◆ get_stamina_max()

int Character::get_stamina_max ( ) const

Definition at line 7091 of file character.cpp.

7092{
7093 static const std::string player_max_stamina( "PLAYER_MAX_STAMINA" );
7094 static const std::string max_stamina_modifier( "max_stamina_modifier" );
7095 const int baseMaxStamina = get_option< int >( player_max_stamina );
7096 int maxStamina = baseMaxStamina;
7097 maxStamina *= Character::mutation_value( max_stamina_modifier );
7098 maxStamina += bonus_from_enchantments( maxStamina, enchant_vals::mod::STAMINA_CAP );
7099 return std::max( baseMaxStamina / 10, maxStamina );
7100}

References bonus_from_enchantments(), mutation_value(), and enchant_vals::STAMINA_CAP.

Referenced by attack_cost(), block_hit(), can_run(), debug_menu::character_edit_menu(), cough(), player_activity::do_turn(), draw_char_narrow(), draw_char_wide(), draw_health_classic(), draw_limb2(), spell::energy_cost_string(), spell::energy_cur_string(), mod_stamina(), character_funcs::normalize(), on_dodge(), on_item_takeoff(), on_item_wear(), npc::process_turn(), activity_handlers::pulp_do_turn(), avatar::read(), speed_rating(), stamina_move_cost_modifier(), game::start_game(), iuse::stimpack(), ranged::time_to_attack(), update_stamina(), activity_handlers::wait_stamina_do_turn(), and activity_handlers::wait_stamina_finish().

◆ get_stashed_activity()

player_activity Character::get_stashed_activity ( ) const

Definition at line 908 of file character.cpp.

909{
911}

References stashed_outbounds_activity.

Referenced by npc::move().

◆ get_stim()

◆ get_stored_kcal()

◆ get_str()

◆ get_str_base()

int Character::get_str_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4105 of file character.cpp.

4106{
4107 return str_max;
4108}

References str_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_str(), avatar::get_str_base(), and recalc_hp().

◆ get_str_bonus()

int Character::get_str_bonus ( ) const
virtual

Definition at line 4122 of file character.cpp.

4123{
4124 return str_bonus;
4125}

References str_bonus.

Referenced by reset_stats().

◆ get_thirst()

◆ get_thirst_description()

std::pair< std::string, nc_color > Character::get_thirst_description ( ) const

Definition at line 4356 of file character.cpp.

4357{
4358 int thirst = get_thirst();
4359 std::string hydration_string;
4360 nc_color hydration_color = c_white;
4362 hydration_color = c_light_red;
4363 hydration_string = _( "Parched" );
4364 } else if( thirst > thirst_levels::dehydrated ) {
4365 hydration_color = c_light_red;
4366 hydration_string = _( "Dehydrated" );
4367 } else if( thirst > thirst_levels::very_thirsty ) {
4368 hydration_color = c_yellow;
4369 hydration_string = _( "Very thirsty" );
4370 } else if( thirst > thirst_levels::thirsty ) {
4371 hydration_color = c_yellow;
4372 hydration_string = _( "Thirsty" );
4373 } else if( thirst > thirst_levels::slaked ) {
4374 // Nothing
4375 } else if( thirst > thirst_levels::hydrated ) {
4376 hydration_color = c_green;
4377 hydration_string = _( "Hydrated" );
4378 } else if( thirst > thirst_levels::turgid ) {
4379 hydration_color = c_green;
4380 hydration_string = _( "Turgid" );
4381 }
4382 return std::make_pair( hydration_string, hydration_color );
4383}

References _, c_green, c_light_red, c_white, c_yellow, dehydrated, get_thirst(), hydrated, parched, slaked, thirst, thirsty, turgid, and very_thirsty.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), npc::faction_display(), and get_consume_needs_hint().

◆ get_time_died()

time_point Character::get_time_died ( ) const
inline

return the calendar::turn the character expired

Definition at line 1475 of file character.h.

1475 {
1476 return time_died;
1477 }
time_point time_died
Definition: character.h:2189

References time_died.

◆ get_total_bionics_slots()

int Character::get_total_bionics_slots ( const bodypart_id bp) const

Definition at line 2593 of file bionics.cpp.

2594{
2595 return bp->bionic_slots();
2596}

Referenced by get_free_bionics_slots(), and show_bionics_ui().

◆ get_total_fuel_capacity()

int Character::get_total_fuel_capacity ( const itype_id fuel) const

Return total space to store specified fuel.

Definition at line 2053 of file character.cpp.

2054{
2055 int capacity = 0;
2056 for( const bionic_id &bid : get_bionics() ) {
2057 for( const itype_id &fl : bid->fuel_opts ) {
2058 if( get_value( bid.str() ).empty() || get_value( bid.str() ) == fl.str() ) {
2059 if( fl == fuel ) {
2060 capacity += bid->fuel_capacity;
2061 }
2062 }
2063 }
2064 }
2065 return capacity;
2066}

References get_bionics(), Creature::get_value(), and string_id< T >::str().

Referenced by draw_bionics_titlebar().

◆ get_type_of_scent()

scenttype_id Character::get_type_of_scent ( ) const

Definition at line 8761 of file character.cpp.

8762{
8763 return type_of_scent;
8764}
scenttype_id type_of_scent
Definition: character.h:2271

References type_of_scent.

Referenced by game::do_turn(), update_type_of_scent(), and change_scent_iuse::use().

◆ get_used_bionics_slots()

int Character::get_used_bionics_slots ( const bodypart_id bp) const

Definition at line 2565 of file bionics.cpp.

2566{
2567 int used_slots = 0;
2568 for( const bionic_id &bid : get_bionics() ) {
2569 auto search = bid->occupied_bodyparts.find( bp.id() );
2570 if( search != bid->occupied_bodyparts.end() ) {
2571 used_slots += search->second;
2572 }
2573 }
2574
2575 return used_slots;
2576}
static bool search(const ui_adaptor &om_ui, tripoint_abs_omt &curs, const tripoint_abs_omt &orig)

References get_bionics(), int_id< T >::id(), and overmap_ui::search().

Referenced by get_free_bionics_slots().

◆ get_visible_creatures()

std::vector< Creature * > Character::get_visible_creatures ( int  range) const

Returns all creatures that this player can see and that are in the given range.

This player object itself is never included. The player character (g->u) is checked and might be included (if applicable).

Parameters
rangeThe maximal distance (rl_dist), creatures at this distance or less are included.

Definition at line 10229 of file character.cpp.

10230{
10231 return g->get_creatures_if( [this, range]( const Creature & critter ) -> bool {
10232 return this != &critter && pos() != critter.pos() && // TODO: get rid of fake npcs (pos() check)
10233 rl_dist( pos(), critter.pos() ) <= range && sees( critter );
10234 } );
10235}

References g, Creature::pos(), pos(), range, rl_dist(), and sees().

Referenced by game::is_hostile_within(), game::list_items_monsters(), and game::mon_info_update().

◆ get_vision_modes()

const std::bitset< NUM_VISION_MODES > & Character::get_vision_modes ( ) const
inline

Definition at line 1553 of file character.h.

1553 {
1554 return vision_mode_cache;
1555 }

References vision_mode_cache.

◆ get_vision_threshold()

float Character::get_vision_threshold ( float  light_level) const

Returns the apparent light level at which the player can see.

This is adjusted by the light level at the character's position to simulate glare, etc, night vision only works if you are in the dark.

Definition at line 1735 of file character.cpp.

1736{
1738 // Debug vision always works with absurdly little light.
1739 return 0.01;
1740 }
1741
1742 // As light_level goes from LIGHT_AMBIENT_MINIMAL to LIGHT_AMBIENT_LIT,
1743 // dimming goes from 1.0 to 2.0.
1744 const float dimming_from_light = 1.0 + ( ( static_cast<float>( light_level ) -
1747
1748 // -1 because SOME math was changed from LIGHT_AMBIENT_MINIMAL to LIGHT_AMBIENT_LOW
1749 // but kept in other places.
1750 // *_LOW is the one actually used in math, *_MINIMAL is arbitrary.
1751 // TODO: Correct test cases and drop the ugliness
1752
1753 // This guarantees at least 1 tile of range
1754 static const float threshold_cap = vision::threshold_for_nv_range( 1 - 1 ) * LIGHT_AMBIENT_LOW /
1756
1757 return std::min( {static_cast<float>( LIGHT_AMBIENT_LOW ),
1758 vision::threshold_for_nv_range( nv_range - 1 ) * dimming_from_light,
1759 threshold_cap} );
1760}
float nv_range
Definition: character.h:2184
static constexpr float LIGHT_AMBIENT_MINIMAL
Definition: lightmap.h:12
static constexpr float LIGHT_AMBIENT_LOW
Definition: lightmap.h:14
static constexpr float LIGHT_AMBIENT_LIT
Definition: lightmap.h:18
float threshold_for_nv_range(float range)
Returns the light level that darkness will have at this range from player.
Definition: character.cpp:1715

References DEBUG_NIGHTVISION, LIGHT_AMBIENT_LIT, LIGHT_AMBIENT_LOW, LIGHT_AMBIENT_MINIMAL, nv_range, vision::threshold_for_nv_range(), and vision_mode_cache.

Referenced by sight_range().

◆ get_weight()

units::mass Character::get_weight ( ) const
overridevirtual

Returns body weight plus weight of inventory and worn/wielded items.

Implements Creature.

Definition at line 3687 of file character.cpp.

3688{
3689 units::mass ret = 0_gram;
3690 units::mass wornWeight = std::accumulate( worn.begin(), worn.end(), 0_gram,
3691 []( units::mass sum, const item & itm ) {
3692 return sum + itm.weight();
3693 } );
3694
3695 ret += bodyweight(); // The base weight of the player's body
3696 ret += inv.weight(); // Weight of the stored inventory
3697 ret += wornWeight; // Weight of worn items
3698 const item &weapon = primary_weapon();
3699 ret += weapon.weight(); // Weight of wielded item
3700 ret += bionics_weight(); // Weight of installed bionics
3701 return ret;
3702}
units::mass bionics_weight() const
Definition: character.cpp:6761
units::mass bodyweight() const
Definition: character.cpp:6756
units::mass weight() const
Definition: inventory.cpp:997

References bionics_weight(), bodyweight(), inv, primary_weapon(), cata::hash64_detail::ret, inventory::weight(), item::weight(), and worn.

Referenced by vehicle::calc_mass_center(), can_mount(), npc::move_to(), monexamine::pet_menu(), swim_speed(), weigh_self_actor::use(), and game::walk_move().

◆ get_weight_string()

std::string Character::get_weight_string ( ) const

Definition at line 4560 of file character.cpp.

4561{
4562 double weight = convert_weight( bodyweight() );
4563 int display_weight = static_cast<int>( std::round( weight ) );
4564 return std::to_string( display_weight ) + " " + weight_units();
4565}
const char * weight_units()
Create a units label for a weight value.
double convert_weight(const units::mass &weight)
Convert weight in grams to units defined by user (kg or lbs)

References bodyweight(), convert_weight(), to_string(), and weight_units().

◆ get_working_arm_count()

int Character::get_working_arm_count ( ) const

Returns the number of functioning arms.

Definition at line 1227 of file character.cpp.

1228{
1230 return 0;
1231 }
1232
1233 int limb_count = 0;
1234 if( !is_limb_disabled( bodypart_id( "arm_l" ) ) ) {
1235 limb_count++;
1236 }
1237 if( !is_limb_disabled( bodypart_id( "arm_r" ) ) ) {
1238 limb_count++;
1239 }
1240
1241 return limb_count;
1242}
static const trait_id trait_SHELL2("SHELL2")

References has_active_mutation(), is_limb_disabled(), and trait_SHELL2.

Referenced by can_wield(), has_two_arms(), melee_attack(), avatar_action::plthrow(), and vehicle::start_engine().

◆ get_working_leg_count()

int Character::get_working_leg_count ( ) const

Returns the number of functioning legs.

Definition at line 1245 of file character.cpp.

1246{
1247 int limb_count = 0;
1248 if( !is_limb_broken( bodypart_id( "leg_l" ) ) ) {
1249 limb_count++;
1250 }
1251 if( !is_limb_broken( bodypart_id( "leg_r" ) ) ) {
1252 limb_count++;
1253 }
1254 return limb_count;
1255}

References is_limb_broken().

Referenced by best_shield(), character_martial_arts::can_leg_block(), can_run(), is_on_ground(), and avatar::set_movement_mode().

◆ getID()

character_id Character::getID ( ) const

Definition at line 494 of file character.cpp.

495{
496 return this->id;
497}

References id.

Referenced by add_addiction(), item::already_used_by_player(), talk_effect_t::apply(), apply_damage(), iuse::artifact(), mission::assign(), talk_function::assign_camp(), vehicle::assign_seat(), best_installer(), bionics_install_failure(), map::board_vehicle(), veh_interact::calc_overview(), debug_menu::character_edit_menu(), check_needs_extremes(), talk_function::clear_mission(), game::critter_by_id(), iuse::crowbar(), mattack::dermatik(), monster::die(), npc::die(), avatar::do_read(), npc::execute_action(), dig_activity_actor::finish(), hacking_activity_actor::finish(), npc::finish_read(), ranged::fire_gun(), talk_function::follow(), item::get_remaining_chapters(), hardcoded_effects(), heal(), talk_function::hostile(), hurtall(), npc::is_ally(), item_location::impl::item_on_person::item_on_person(), talk_function::leave(), avatar::load(), game::load(), npc::load_npc_template(), item::mark_as_used_by_player(), item::mark_chapter_as_read(), iuse::marloss(), marloss_common(), iuse::marloss_gel(), iuse::marloss_seed(), mend(), iuse::mininuke(), mount_creature(), mutagen_common_checks(), mutate_towards(), npc::mutiny(), iuse::mycus(), iuse::note_bionics(), kill_tracker::notify(), talk_function::npc_die(), mattack::nurse_operate(), mission::on_creature_death(), item::on_pickup(), item::on_wield(), perform_install(), perform_uninstall(), practice(), npc::randomize(), avatar::read(), npc::regen_ai_cache(), rem_addiction(), Creature::remove_effect(), game::reset_npc_dispositions(), map::rotate(), talk_effect_fun_t::set_add_mission(), vehicle_part::set_crew(), npc::set_fac(), npc::set_known_to_u(), npc::setpos(), game::start_game(), npc::start_read(), talk_function::start_training(), talk_function::stop_guard(), player::store(), survive_random_encounter(), npc::talk_to_u(), teleport::teleport(), test_crossing_threshold(), ranged::throw_item(), activity_handlers::train_finish(), npc::travel_overmap(), game::validate_npc_followers(), vomit(), and wake_up().

◆ gibType()

field_type_id Character::gibType ( ) const
overridevirtual

Implements Creature.

Definition at line 524 of file character.cpp.

525{
526 return fd_gibs_flesh;
527}
field_type_id fd_gibs_flesh
Definition: field_type.cpp:338

References fd_gibs_flesh.

◆ global_omt_location()

tripoint_abs_omt Character::global_omt_location ( ) const

Returns the location of the player in global overmap terrain coordinates.

Definition at line 6268 of file character.cpp.

6269{
6270 // TODO: fix point types
6272}
virtual tripoint global_square_location() const
Global position, expressed in map square coordinate system (the most detailed coordinate system),...
Definition: character.cpp:6258
point ms_to_omt_copy(point p)
coords::coord_point< tripoint, coords::origin::abs, coords::omt > tripoint_abs_omt
Definition: coordinates.h:493

References global_square_location(), and ms_to_omt_copy().

Referenced by talk_function::abandon_camp(), computer_session::action_map_sewer(), computer_session::action_map_subway(), computer_session::action_maps(), activate_bionic(), activate_mutation(), apply_persistent_morale(), iuse::artifact(), talk_function::assign_camp(), talk_function::basecamp_mission(), burn_fuel(), talk_function::caravan_dist(), ui::omap::choose_point(), talk_function::companion_choose_return(), talk_function::companion_list(), talk_function::companion_mission(), npc::consume_food_from_camp(), mission_start::create_hidden_lab_console(), mission_start::create_ice_lab_console(), mission_start::create_lab_console(), game::disp_NPCs(), item::display_name(), ui::omap::display_visible_weather(), ui::omap::display_weather(), game::do_turn(), overmap_ui::draw_ascii(), draw_env_compact(), draw_loc_labels(), draw_location_classic(), game::draw_minimap(), draw_minimap(), basecamp::faction_display(), npc::faction_display(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), mission_start::find_safety(), overmapbuffer::fix_npcs(), get_basecamp(), get_mission_om_origin(), overmapbuffer::get_npcs_near_omt(), overmapbuffer::get_npcs_near_player(), overmap_ui::get_overmap_path_to(), npc::go_to_omt_destination(), talk_function::goto_location(), npc::guard_current_pos(), talk_function::individual_mission(), mission_start::kill_horde_master(), game::list_missions(), spell_effect::map_area(), trapfunc::map_regen(), npc::move(), overmap_los(), passive_power_gen(), game::perhaps_add_random_npc(), mission_start::place_deposit_box(), mission_start::place_npc_software(), process_turn(), npc::reach_omt_destination(), talk_function::recover_camp(), teleporter_callback::refresh(), npc::regen_ai_cache(), render_wind(), game::reset_npc_dispositions(), reveal_destination(), mission_start::reveal_lab_train_depot(), mission_util::reveal_om_ter(), conditional_t< T >::set_at_om_location(), npc::set_companion_mission(), npc::set_omt_destination(), talk_function::start_camp(), game::start_game(), activity_handlers::travel_do_turn(), npc::travel_overmap(), activity_handlers::tree_communion_do_turn(), update_bodytemp(), game::update_overmap_seen(), reveal_map_actor::use(), game::vertical_notes(), iuse::weather_tool(), npc::within_boundaries_of_camp(), and game::zones_manager().

◆ global_sm_location()

tripoint Character::global_sm_location ( ) const

◆ global_square_location()

tripoint Character::global_square_location ( ) const
virtual

Global position, expressed in map square coordinate system (the most detailed coordinate system), used by the map.

Reimplemented in npc.

Definition at line 6258 of file character.cpp.

6259{
6260 return get_map().getabs( position );
6261}
tripoint position
Definition: character.h:2129

References get_map(), map::getabs(), and position.

Referenced by global_omt_location(), and global_sm_location().

◆ handle_melee_wear()

bool Character::handle_melee_wear ( item shield,
float  wear_multiplier = 1.0f 
)

Calculates melee weapon wear-and-tear through use, returns true if item is destroyed.

Dexterity reduces chance of damaging your melee weapon Strength increases chance of damaging your melee weapon (NEGATIVE) Melee reduces chance of damaging your melee weapon

Definition at line 216 of file melee.cpp.

217{
218 if( wear_multiplier <= 0.0f ) {
219 return false;
220 }
221 // Here is where we handle wear and tear on things we use as melee weapons or shields.
222 if( shield.is_null() ) {
223 return false;
224 }
225
226 // UNBREAKABLE_MELEE items can't be damaged through melee combat usage.
227 if( shield.has_flag( "UNBREAKABLE_MELEE" ) ) {
228 return false;
229 }
230
231 /** @EFFECT_DEX reduces chance of damaging your melee weapon */
232
233 /** @EFFECT_STR increases chance of damaging your melee weapon (NEGATIVE) */
234
235 /** @EFFECT_MELEE reduces chance of damaging your melee weapon */
236 const float stat_factor = dex_cur / 2.0f
238 + ( 64.0f / std::max( str_cur, 4 ) );
239
240 float material_factor;
241
242 itype_id weak_comp;
243 itype_id big_comp = itype_id::NULL_ID();
244 // Fragile items that fall apart easily when used as a weapon due to poor construction quality
245 if( shield.has_flag( "FRAGILE_MELEE" ) ) {
246 const float fragile_factor = 6;
247 int weak_chip = INT_MAX;
248 units::volume big_vol = 0_ml;
249
250 // Items that should have no bearing on durability
251 const std::set<itype_id> blacklist = { itype_rag, itype_leather, itype_fur };
252
253 for( auto &comp : shield.components ) {
254 if( blacklist.count( comp.typeId() ) <= 0 ) {
255 if( weak_chip > comp.chip_resistance() ) {
256 weak_chip = comp.chip_resistance();
257 weak_comp = comp.typeId();
258 }
259 }
260 if( comp.volume() > big_vol ) {
261 big_vol = comp.volume();
262 big_comp = comp.typeId();
263 }
264 }
265 material_factor = ( weak_chip < INT_MAX ? weak_chip : shield.chip_resistance() ) / fragile_factor;
266 } else {
267 material_factor = shield.chip_resistance();
268 }
269 int damage_chance = static_cast<int>( stat_factor * material_factor / wear_multiplier );
270 // DURABLE_MELEE items are made to hit stuff and they do it well, so they're considered to be a lot tougher
271 // than other weapons made of the same materials.
272 if( shield.has_flag( "DURABLE_MELEE" ) ) {
273 damage_chance *= 4;
274 }
275
276 if( damage_chance > 0 && !one_in( damage_chance ) ) {
277 return false;
278 }
279
280 auto str = shield.tname(); // save name before we apply damage
281
282 if( !shield.inc_damage() ) {
283 add_msg_player_or_npc( m_bad, _( "Your %s is damaged by the force of the blow!" ),
284 _( "<npcname>'s %s is damaged by the force of the blow!" ),
285 str );
286 return false;
287 }
288
289 // Dump its contents on the ground
290 // Destroy irremovable mods, if any
291
292 for( auto mod : shield.gunmods() ) {
293 if( mod->is_irremovable() ) {
294 remove_item( *mod );
295 }
296 }
297
298 // Preserve item temporarily for component breakdown
299 item temp = shield;
300
301 shield.contents.spill_contents( pos() );
302
303 remove_item( shield );
304
305 // Breakdown fragile weapons into components
306 if( temp.has_flag( "FRAGILE_MELEE" ) && !temp.components.empty() ) {
307 add_msg_player_or_npc( m_bad, _( "Your %s breaks apart!" ),
308 _( "<npcname>'s %s breaks apart!" ),
309 str );
310
311 for( auto &comp : temp.components ) {
312 int break_chance = comp.typeId() == weak_comp ? 2 : 8;
313
314 if( one_in( break_chance ) ) {
315 add_msg_if_player( m_bad, _( "The %s is destroyed!" ), comp.tname() );
316 continue;
317 }
318
319 if( comp.typeId() == big_comp && !is_armed() ) {
320 wield( comp );
321 } else {
322 g->m.add_item_or_charges( pos(), comp );
323 }
324 }
325 } else {
326 add_msg_player_or_npc( m_bad, _( "Your %s is destroyed by the blow!" ),
327 _( "<npcname>'s %s is destroyed by the blow!" ),
328 str );
329 }
330
331 return true;
332}
virtual bool wield(item &target)=0
Removes currently wielded item (if any) and replaces it with the target item.
bool spill_contents(const tripoint &pos)
int chip_resistance(bool worst=false) const
Returns resistance to being damaged by attack against the item itself.
Definition: item.cpp:6217
bool inc_damage(damage_type dt)
Increment item damage by itype::damage_scale constrained by max_damage.
Definition: item.cpp:6278
std::vector< item * > gunmods()
Returns all gunmods currently attached to this item (always empty if item not a gun)
Definition: item.cpp:7752
static const itype_id itype_rag("rag")
static const itype_id itype_fur("fur")
static const itype_id itype_leather("leather")

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), item::chip_resistance(), item::components, item::contents, dex_cur, g, get_skill_level(), item::gunmods(), item::has_flag(), item::inc_damage(), is_armed(), item::is_null(), itype_fur, itype_leather, itype_rag, m_bad, string_id< itype >::NULL_ID(), one_in(), pos(), visitable< Character >::remove_item(), skill_melee, item_contents::spill_contents(), str_cur, item::tname(), and wield().

Referenced by block_hit(), block_ranged_hit(), melee_special_effects(), reach_attack(), and smash().

◆ hardcoded_effects()

void Character::hardcoded_effects ( effect it)

Handles the still hard-coded effects.

Maximum Strength increases number of insects hatched from dermatik infection Intelligence decreases occurrence of itching from formication effect

Definition at line 472 of file player_hardcoded_effects.cpp.

473{
474 if( auto buff = ma_buff::from_effect( it ) ) {
475 if( buff->is_valid_character( *this ) ) {
476 buff->apply_character( *this );
477 } else {
478 it.set_duration( 0_turns ); // removes the effect
479 }
480 return;
481 }
482 using hc_effect_fun = std::function<void( player &, effect & )>;
483 static const std::map<efftype_id, hc_effect_fun> hc_effect_map = {{
496 }
497 };
498 const efftype_id &id = it.get_id();
499 const auto &iter = hc_effect_map.find( id );
500 if( iter != hc_effect_map.end() ) {
501 iter->second( *as_player(), it );
502 return;
503 }
504
505 const time_duration dur = it.get_duration();
506 int intense = it.get_intensity();
507 body_part bp = it.get_bp()->token;
508 bool sleeping = has_effect( effect_sleep );
509 if( id == effect_dermatik ) {
510 bool triggered = false;
511 int formication_chance = 3600;
512 if( dur < 4_hours ) {
513 formication_chance += 14400 - to_turns<int>( dur );
514 }
515 if( one_in( formication_chance ) ) {
516 add_effect( effect_formication, 60_minutes, bp );
517 }
518 if( dur < 1_days && one_in( 14400 ) ) {
519 vomit();
520 }
521 if( dur > 1_days ) {
522 // Spawn some larvae!
523 // Choose how many insects; more for large characters
524 ///\EFFECT_STR_MAX increases number of insects hatched from dermatik infection
525 int num_insects = rng( 1, std::min( 3, str_max / 3 ) );
526 apply_damage( nullptr, convert_bp( bp ).id(), rng( 2, 4 ) * num_insects );
527 // Figure out where they may be placed
529 _( "Your flesh crawls; insects tear through the flesh and begin to emerge!" ),
530 _( "Insects begin to emerge from <npcname>'s skin!" ) );
531 for( ; num_insects > 0; num_insects-- ) {
532 if( monster *const grub = g->place_critter_around( mon_dermatik_larva, pos(), 1 ) ) {
533 if( one_in( 3 ) ) {
534 grub->friendly = -1;
535 }
536 }
537 }
538 g->events().send<event_type::dermatik_eggs_hatch>( getID() );
540 moves -= 600;
541 triggered = true;
542 }
543 if( triggered ) {
544 // Set ourselves up for removal
545 it.set_duration( 0_turns );
546 } else {
547 // Count duration up
548 it.mod_duration( 1_turns );
549 }
550 } else if( id == effect_formication ) {
551 ///\EFFECT_INT decreases occurrence of itching from formication effect
552 if( x_in_y( intense, 600 + 300 * get_int() ) && !has_effect( effect_narcosis ) ) {
553 if( !is_npc() ) {
554 //~ %s is bodypart in accusative.
555 add_msg( m_warning, _( "You start scratching your %s!" ), body_part_name_accusative( bp ) );
556 g->u.cancel_activity();
557 } else if( g->u.sees( pos() ) ) {
558 //~ 1$s is NPC name, 2$s is bodypart in accusative.
559 add_msg( _( "%1$s starts scratching their %2$s!" ), name, body_part_name_accusative( bp ) );
560 }
561 moves -= 150;
562 apply_damage( nullptr, convert_bp( bp ).id(), 1 );
563 }
564 } else if( id == effect_evil ) {
565 // Worn or wielded; diminished effects
566 bool lesserEvil = primary_weapon().has_effect_when_wielded( AEP_EVIL ) ||
568 for( auto &w : worn ) {
569 if( w.has_effect_when_worn( AEP_EVIL ) ) {
570 lesserEvil = true;
571 break;
572 }
573 }
574 if( lesserEvil ) {
575 // Only minor effects, some even good!
576 mod_str_bonus( dur > 450_minutes ? 10.0 : dur / 45_minutes );
577 if( dur < 1_hours ) {
578 mod_dex_bonus( 1 );
579 } else {
580 int dex_mod = -( dur > 360_minutes ? 10.0 : ( dur - 1_hours ) / 30_minutes );
581 mod_dex_bonus( dex_mod );
582 add_miss_reason( _( "Why waste your time on that insignificant speck?" ), -dex_mod );
583 }
584 mod_int_bonus( -( dur > 300_minutes ? 10.0 : ( dur - 50_minutes ) / 25_minutes ) );
585 mod_per_bonus( -( dur > 480_minutes ? 10.0 : ( dur - 80_minutes ) / 40_minutes ) );
586 } else {
587 // Major effects, all bad.
588 mod_str_bonus( -( dur > 500_minutes ? 10.0 : dur / 50_minutes ) );
589 int dex_mod = -( dur > 600_minutes ? 10.0 : dur / 60_minutes );
590 mod_dex_bonus( dex_mod );
591 add_miss_reason( _( "Why waste your time on that insignificant speck?" ), -dex_mod );
592 mod_int_bonus( -( dur > 450_minutes ? 10.0 : dur / 45_minutes ) );
593 mod_per_bonus( -( dur > 400_minutes ? 10.0 : dur / 40_minutes ) );
594 }
595 } else if( id == effect_attention ) {
596 if( intense > 6 ) {
597 if( one_in( 7200 - ( intense * 450 ) ) ) {
599 _( "You feel something reaching out to you, before reality around you frays!" ) );
600 if( has_psy_protection( *this, 10 ) ) {
601 // Transfers half of remaining duration of nether attention, tinfoil only sometimes helps
602 add_effect( effect_teleglow, ( dur / 2 ), num_bp, ( intense / 2 ) );
603 } else {
604 // Transfers all remaining duration of nether attention to dimensional instability
605 add_effect( effect_teleglow, dur, num_bp, intense );
606 }
607 it.set_duration( 0_turns );
608 }
609 if( one_in( 8000 - ( intense * 500 ) ) && one_in( 2 ) ) {
610 if( !is_npc() ) {
611 add_msg( m_bad, _( "You pass out from the strain of something bearing down on your mind." ) );
612 }
613 fall_asleep( 2_hours );
614 if( one_in( 10 ) ) {
615 it.set_duration( 0_turns );
616 }
617 it.mod_duration( -20_minutes * intense );
618 it.mod_intensity( -1 );
619 }
620 }
621 if( intense > 4 ) {
622 if( one_in( 6000 - ( intense * 375 ) ) ) {
623 if( has_psy_protection( *this, 4 ) ) {
624 add_msg_if_player( m_bad, _( "You feel something probing your mind, but it is rebuffed!" ) );
625 } else {
626 add_msg_if_player( m_bad, _( "A terrifying image in the back out your mind paralyzes you." ) );
628 moves -= 4 * get_speed();
629 }
630 it.mod_duration( -10_minutes * intense );
631 if( one_in( 2 ) ) {
632 it.mod_intensity( -1 );
633 }
634 }
635 if( one_turn_in( 1200_minutes - ( intense * 90_minutes ) ) ) {
636 if( has_psy_protection( *this, 4 ) ) {
637 add_msg_if_player( m_bad, _( "You feel a buzzing in the back of your mind, but it passes." ) );
638 } else {
639 add_msg_if_player( m_bad, _( "You feel something scream in the back of your mind!" ) );
640 add_effect( effect_dazed, rng( 1_minutes, 2_minutes ) );
641 }
642 it.mod_duration( -10_minutes * intense );
643 if( one_in( 3 ) ) {
644 it.mod_intensity( -1 );
645 }
646 }
647 }
648 if( intense > 2 ) {
649 if( one_turn_in( 1200_minutes - ( intense * 90_minutes ) ) ) {
650 add_msg_if_player( m_bad, _( "Your vision is filled with bright lights…" ) );
651 add_effect( effect_blind, rng( 1_minutes, 2_minutes ) );
652 it.mod_duration( -10_minutes * intense );
653 if( one_in( 4 ) ) {
654 it.mod_intensity( -1 );
655 }
656 }
657 if( one_in( 5000 ) && !has_effect( effect_nausea ) ) {
658 add_msg_if_player( m_bad, _( "A wave of nausea passes over you." ) );
659 add_effect( effect_nausea, 5_minutes );
660 }
661 }
662 if( one_in( 5000 ) && !has_effect( effect_hallu ) ) {
663 add_msg_if_player( m_bad, _( "Shifting shapes dance on the edge of your vision." ) );
664 add_effect( effect_hallu, 4_hours );
665 it.mod_duration( -10_minutes * intense );
666 }
667 if( one_turn_in( 40_minutes ) ) {
668 if( has_psy_protection( *this, 4 ) ) {
669 add_msg_if_player( m_bad, _( "You feel weird for a moment, but it passes." ) );
670 } else {
671 // Less morale drop and faster decay than Psychosis negative messages, but more frequent
672 const translation snip = SNIPPET.random_from_category( "nether_attention_watching" ).value_or(
673 translation() );
674 add_msg_if_player( m_warning, "%s", snip );
675 add_morale( MORALE_FEELING_BAD, -10, -50, 60_minutes, 20_minutes, true );
676 }
677 }
678 } else if( id == effect_teleglow ) {
679 // Each teleportation increases intensity by 1, 2 intensities per tier of effect.
680 // TODO: Include a chance to teleport to the nether realm.
681 // TODO: This with regards to NPCS
682 if( !is_player() ) {
683 // NO, no teleporting around the player because an NPC has teleglow!
684 return;
685 }
686 if( intense > 6 ) {
687 if( one_in( 6000 - ( intense * 250 ) ) ) {
688 if( !is_npc() ) {
689 add_msg( _( "Glowing lights surround you, and you teleport." ) );
690 }
691 teleport::teleport( *this );
692 g->events().send<event_type::teleglow_teleports>( getID() );
693 if( one_in( 10 ) ) {
694 // Set ourselves up for removal
695 it.set_duration( 0_turns );
696 }
697 // Since teleporting grants 1 intensity and 30 minutes duration,
698 // if it doesn't remove it'll get more intense but shorter.
699 it.mod_duration( -20_minutes * intense );
700 }
701 if( one_in( 7200 - ( intense * 250 ) ) ) {
702 add_msg_if_player( m_bad, _( "You are beset with a vision of a prowling beast." ) );
703 for( const tripoint &dest : g->m.points_in_radius( pos(), 6 ) ) {
704 if( g->m.is_cornerfloor( dest ) ) {
705 g->m.add_field( dest, fd_tindalos_rift, 3 );
706 add_msg_if_player( m_info, _( "Your surroundings are permeated with a foul scent." ) );
707 break;
708 }
709 }
710 if( one_in( 2 ) ) {
711 // Set ourselves up for removal
712 it.set_duration( 0_turns );
713 }
714 it.mod_intensity( -1 );
715 }
716 }
717 if( intense > 4 ) {
718 // Once every 4 hours baseline, once every 2 hours max
719 if( one_turn_in( 14_hours - ( intense * 90_minutes ) ) ) {
720 tripoint dest( 0, 0, posz() );
721 int &x = dest.x;
722 int &y = dest.y;
723 int tries = 0;
724 do {
725 x = posx() + rng( -4, 4 );
726 y = posy() + rng( -4, 4 );
727 tries++;
728 if( tries >= 10 ) {
729 break;
730 }
731 } while( g->critter_at( dest ) );
732 if( tries < 10 ) {
733 if( g->m.impassable( dest ) ) {
734 g->m.make_rubble( dest, f_rubble_rock );
735 }
737 GROUP_NETHER );
738 g->place_critter_at( spawn_details.name, dest );
739 if( g->u.sees( dest ) ) {
740 g->cancel_activity_or_ignore_query( distraction_type::hostile_spotted_far,
741 _( "A monster appears nearby!" ) );
742 add_msg( m_warning, _( "A portal opens nearby, and a monster crawls through!" ) );
743 }
744 it.mod_duration( -10_minutes * intense );
745 it.mod_intensity( -1 );
746 }
747 }
748 if( one_in( 21000 - ( intense * 1125 ) ) ) {
749 add_msg_if_player( m_bad, _( "You shudder suddenly." ) );
750 mutate();
751 it.mod_duration( -10_minutes * intense );
752 if( one_in( 2 ) ) {
753 it.mod_intensity( -1 );
754 }
755 }
756 }
757 if( intense > 2 ) {
758 if( one_in( 10000 ) ) {
759 if( !has_trait( trait_M_IMMUNE ) ) {
760 add_effect( effect_fungus, 1_turns, num_bp );
761 add_msg_if_player( m_bad, _( "You smell mold, and your skin itches." ) );
762 } else {
763 add_msg_if_player( m_info, _( "We have many colonists awaiting passage." ) );
764 }
765 // Set ourselves up for removal
766 it.set_duration( 0_turns );
767 }
768 if( one_in( 5000 ) ) {
769 // Like with the glow anomaly trap, but lower max and bypasses radsuits
770 add_msg_if_player( m_bad, _( "A blue flash of radiation permeates your vision briefly!" ) );
771 irradiate( rng( 10, 20 ), true );
772 it.mod_duration( -10_minutes * intense );
773 if( one_in( 4 ) ) {
774 it.mod_intensity( -1 );
775 }
776 }
777 }
778 if( one_in( 4000 ) ) {
779 add_msg_if_player( m_bad, _( "You're suddenly covered in ectoplasm." ) );
780 add_effect( effect_boomered, 10_minutes );
781 it.mod_duration( -10_minutes * intense );
782 }
783 if( one_in( 5000 ) ) {
784 add_msg_if_player( m_bad, _( "A strange sound reverberates around the edges of reality." ) );
785 // Comparable to the humming anomaly trap, with a narrower range
786 int volume = rng( 25, 150 );
787 std::string sfx;
788 if( volume <= 50 ) {
789 sfx = _( "hrmmm" );
790 } else if( volume <= 100 ) {
791 sfx = _( "HRMMM" );
792 } else {
793 sfx = _( "VRMMMMMM" );
794 }
795 sounds::sound( pos(), volume, sounds::sound_t::activity, sfx, false, "humming", "machinery" );
796 }
797 } else if( id == effect_asthma ) {
799 add_msg_if_player( m_good, _( "Your asthma attack stops." ) );
800 it.set_duration( 0_turns );
801 } else if( dur > 2_hours ) {
802 add_msg_if_player( m_bad, _( "Your asthma overcomes you.\nYou asphyxiate." ) );
803 g->events().send<event_type::dies_from_asthma_attack>( getID() );
804 hurtall( 500, nullptr );
805 } else if( dur > 70_minutes ) {
806 if( one_in( 120 ) ) {
807 add_msg_if_player( m_bad, _( "You wheeze and gasp for air." ) );
808 }
809 }
810 } else if( id == effect_brainworms ) {
811 if( one_in( 1536 ) ) {
812 add_msg_if_player( m_bad, _( "Your head aches faintly." ) );
813 }
814 if( one_in( 6144 ) ) {
815 mod_healthy_mod( -10, -100 );
816 apply_damage( nullptr, bodypart_id( "head" ), rng( 0, 1 ) );
817 if( !has_effect( effect_visuals ) ) {
818 add_msg_if_player( m_bad, _( "Your vision is getting fuzzy." ) );
819 add_effect( effect_visuals, rng( 1_minutes, 60_minutes ) );
820 }
821 }
822 if( one_in( 24576 ) ) {
823 mod_healthy_mod( -10, -100 );
824 apply_damage( nullptr, bodypart_id( "head" ), rng( 1, 2 ) );
825 if( !is_blind() && !sleeping ) {
826 add_msg_if_player( m_bad, _( "Your vision goes black!" ) );
827 add_effect( effect_blind, rng( 5_turns, 20_turns ) );
828 }
829 }
830 } else if( id == effect_tapeworm ) {
831 if( one_in( 3072 ) ) {
832 add_msg_if_player( m_bad, _( "Your bowels ache." ) );
833 }
834 } else if( id == effect_bloodworms ) {
835 if( one_in( 3072 ) ) {
836 add_msg_if_player( m_bad, _( "Your veins itch." ) );
837 }
838 } else if( id == effect_paincysts ) {
839 if( one_in( 3072 ) ) {
840 add_msg_if_player( m_bad, _( "Your muscles feel like they're knotted and tired." ) );
841 }
842 } else if( id == effect_datura ) {
843 if( dur > 100_minutes && focus_pool >= 1 && one_in( 24 ) ) {
844 focus_pool--;
845 }
846 if( dur > 200_minutes && one_in( 48 ) && get_stim() < 20 ) {
847 mod_stim( 1 );
848 }
849 if( dur > 300_minutes && focus_pool >= 1 && one_in( 12 ) ) {
850 focus_pool--;
851 }
852 if( dur > 400_minutes && one_in( 384 ) ) {
853 mod_pain( rng( -1, -8 ) );
854 }
855 if( ( !has_effect( effect_hallu ) ) && ( dur > 500_minutes && one_in( 24 ) ) ) {
856 add_effect( effect_hallu, 6_hours );
857 }
858 if( dur > 600_minutes && one_in( 768 ) ) {
859 mod_pain( rng( -3, -24 ) );
860 if( dur > 800_minutes && one_in( 16 ) ) {
862 _( "You're experiencing loss of basic motor skills and blurred vision. Your mind recoils in horror, unable to communicate with your spinal column." ) );
863 add_msg_if_player( m_bad, _( "You stagger and fall!" ) );
864 add_effect( effect_downed, rng( 1_turns, 4_turns ), num_bp, 0, true );
865 if( one_in( 8 ) || x_in_y( character_effects::vomit_mod( *this ), 10 ) ) {
866 vomit();
867 }
868 }
869 }
870 if( dur > 700_minutes && focus_pool >= 1 ) {
871 focus_pool--;
872 }
873 if( dur > 800_minutes && one_in( 1536 ) ) {
874 add_effect( effect_visuals, rng( 4_minutes, 20_minutes ) );
875 mod_pain( rng( -8, -40 ) );
876 }
877 if( dur > 1200_minutes && one_in( 1536 ) ) {
878 add_msg_if_player( m_bad, _( "There's some kind of big machine in the sky." ) );
879 add_effect( effect_visuals, rng( 8_minutes, 40_minutes ) );
880 if( one_in( 32 ) ) {
881 add_msg_if_player( m_bad, _( "It's some kind of electric snake, coming right at you!" ) );
882 mod_pain( rng( 4, 40 ) );
883 vomit();
884 }
885 }
886 if( dur > 1400_minutes && one_in( 768 ) ) {
888 _( "Order us some golf shoes, otherwise we'll never get out of this place alive." ) );
889 add_effect( effect_visuals, rng( 40_minutes, 200_minutes ) );
890 if( one_in( 8 ) ) {
892 _( "The possibility of physical and mental collapse is now very real." ) );
893 if( one_in( 2 ) || x_in_y( character_effects::vomit_mod( *this ), 10 ) ) {
894 add_msg_if_player( m_bad, _( "No one should be asked to handle this trip." ) );
895 vomit();
896 mod_pain( rng( 8, 40 ) );
897 }
898 }
899 }
900
901 if( dur > 1800_minutes && one_in( 300 * 512 ) ) {
902 if( !has_trait( trait_NOPAIN ) ) {
904 _( "Your heart spasms painfully and stops, dragging you back to reality as you die." ) );
905 } else {
907 _( "You dissolve into beautiful paroxysms of energy. Life fades from your nebulae and you are no more." ) );
908 }
909 g->events().send<event_type::dies_from_drug_overdose>( getID(), id );
910 set_part_hp_cur( bodypart_id( "torso" ), 0 );
911 }
912 } else if( id == effect_grabbed ) {
914 int zed_number = 0;
915 for( auto &dest : g->m.points_in_radius( pos(), 1, 0 ) ) {
916 const monster *const mon = g->critter_at<monster>( dest );
917 if( mon && mon->has_effect( effect_grabbing ) ) {
918 zed_number += mon->get_grab_strength();
919 }
920 }
921 if( zed_number > 0 ) {
922 //If intensity isn't pass the cap, average it with # of zeds
923 add_effect( effect_grabbed, 2_turns, bp_torso, ( intense + zed_number ) / 2 );
924 }
925 } else if( id == effect_bite ) {
926 bool recovered = false;
927 /* Recovery chances, use binomial distributions if balancing here. Healing in the bite
928 * stage provides additional benefits, so both the bite stage chance of healing and
929 * the cumulative chances for spontaneous healing are both given.
930 * Cumulative heal chances for the bite + infection stages:
931 * -200 health - 38.6%
932 * 0 health - 46.8%
933 * 200 health - 53.7%
934 *
935 * Heal chances in the bite stage:
936 * -200 health - 23.4%
937 * 0 health - 28.3%
938 * 200 health - 32.9%
939 *
940 * Cumulative heal chances the bite + infection stages with the resistant mutation:
941 * -200 health - 82.6%
942 * 0 health - 84.5%
943 * 200 health - 86.1%
944 *
945 * Heal chances in the bite stage with the resistant mutation:
946 * -200 health - 60.7%
947 * 0 health - 63.2%
948 * 200 health - 65.6%
949 */
950 if( dur % 10_turns == 0_turns ) {
951 int recover_factor = 100;
952 if( has_effect( effect_recover ) ) {
953 recover_factor -= get_effect_dur( effect_recover ) / 1_hours;
954 }
955 if( has_trait( trait_INFRESIST ) ) {
956 recover_factor += 200;
957 }
958 if( has_effect( effect_panacea ) ) {
959 recover_factor = 648000; //panacea is a guaranteed cure
960 } else if( has_effect( effect_strong_antibiotic ) ) {
961 recover_factor += 400;
962 } else if( has_effect( effect_antibiotic ) ) {
963 recover_factor += 200;
964 } else if( has_effect( effect_weak_antibiotic ) ) {
965 recover_factor += 100;
966 }
967 recover_factor += get_healthy() / 10;
968
969 if( x_in_y( recover_factor, 648000 ) ) {
970 //~ %s is bodypart name.
971 add_msg_if_player( m_good, _( "Your %s wound begins to feel better!" ),
972 body_part_name( bp ) );
973 // Set ourselves up for removal
974 it.set_duration( 0_turns );
975 recovered = true;
976 }
977 }
978 if( !recovered ) {
979 // Move up to infection
980 // Infection resistance can keep us in bite phase arbitrarily long
981 if( dur > 6_hours && !has_trait( trait_INFRESIST ) ) {
982 add_effect( effect_infected, 1_turns, bp );
983 // Set ourselves up for removal
984 it.set_duration( 0_turns );
985 } else if( has_effect( effect_strong_antibiotic ) ) {
986 // Strong antibiotic reverses progress
987 it.mod_duration( -1_turns );
988 } else if( has_effect( effect_antibiotic ) ) {
989 // Normal antibiotic prevents progression
990 } else if( has_effect( effect_weak_antibiotic ) ) {
991 if( calendar::once_every( 4_turns ) ) {
992 // Weak antibiotic slows down to a quarter
993 it.mod_duration( 1_turns );
994 }
995 } else {
996 it.mod_duration( 1_turns );
997 }
998 }
999 } else if( id == effect_infected ) {
1000 bool recovered = false;
1001 // Recovery chance, use binomial distributions if balancing here.
1002 // See "bite" for balancing notes on this.
1003 if( dur % 10_turns == 0_turns ) {
1004 int recover_factor = 100;
1005 if( has_effect( effect_recover ) ) {
1006 recover_factor -= get_effect_dur( effect_recover ) / 1_hours;
1007 }
1008 if( has_trait( trait_INFRESIST ) ) {
1009 recover_factor += 200;
1010 }
1011 if( has_effect( effect_panacea ) ) {
1012 recover_factor = 5184000;
1013 } else if( has_effect( effect_strong_antibiotic ) ) {
1014 recover_factor += 400;
1015 } else if( has_effect( effect_antibiotic ) ) {
1016 recover_factor += 200;
1017 } else if( has_effect( effect_weak_antibiotic ) ) {
1018 recover_factor += 100;
1019 }
1020 recover_factor += get_healthy() / 10;
1021
1022 if( x_in_y( recover_factor, 5184000 ) ) {
1023 //~ %s is bodypart name.
1024 add_msg_if_player( m_good, _( "Your %s wound begins to feel better!" ),
1025 body_part_name( bp ) );
1026 add_effect( effect_recover, 4 * dur );
1027 // Set ourselves up for removal
1028 it.set_duration( 0_turns );
1029 recovered = true;
1030 }
1031 }
1032 if( !recovered ) {
1033 // Don't kill if the player is on antibiotics
1035 it.mod_duration( -1_turns );
1036 } else if( has_effect( effect_antibiotic ) ) {
1037 // No progression
1038 } else if( has_effect( effect_weak_antibiotic ) ) {
1039 if( calendar::once_every( 4_turns ) ) {
1040 it.mod_duration( 1_turns );
1041 }
1042 } else if( dur > 1_days ) {
1043 add_msg_if_player( m_bad, _( "You succumb to the infection." ) );
1044 g->events().send<event_type::dies_of_infection>( getID() );
1045 hurtall( 500, nullptr );
1046 } else {
1047 it.mod_duration( 1_turns );
1048 }
1049 }
1050 } else if( id == effect_lying_down ) {
1051 set_moves( 0 );
1052 if( character_funcs::roll_can_sleep( *this ) ) {
1053 fall_asleep();
1054 // Set ourselves up for removal
1055 it.set_duration( 0_turns );
1056 }
1057 if( dur == 1_turns && !sleeping ) {
1058 add_msg_if_player( _( "You try to sleep, but can't…" ) );
1059 }
1060 } else if( id == effect_sleep ) {
1061 set_moves( 0 );
1062 if( is_avatar() ) {
1064 }
1065
1066 if( has_effect( effect_narcosis ) && get_fatigue() <= 25 ) {
1067 set_fatigue( 25 ); //Prevent us from waking up naturally while under anesthesia
1068 }
1069
1070 if( get_fatigue() <= 10 && !has_effect( effect_narcosis ) ) {
1071 set_fatigue( 0 );
1073 add_msg_if_player( m_good, _( "You feel well rested." ) );
1074 } else {
1076 _( "You feel physically rested, but you haven't been able to catch up on your missed sleep yet." ) );
1077 }
1078 it.set_duration( 0_seconds );
1079 }
1080
1081 // TODO: Move this to update_needs when NPCs can mutate
1082 if( calendar::once_every( 10_minutes ) && ( has_trait( trait_CHLOROMORPH ) ||
1084 g->m.is_outside( pos() ) ) {
1085 if( has_trait( trait_CHLOROMORPH ) ) {
1086 // Hunger and thirst fall before your Chloromorphic physiology!
1087 if( g->natural_light_level( posz() ) >= 12 &&
1088 get_weather().weather_id->sun_intensity >= sun_intensity_type::light ) {
1089 if( get_stored_kcal() < max_stored_kcal() - 50 ) {
1090 mod_stored_kcal( 50 );
1091 }
1093 mod_thirst( -5 );
1094 }
1095 }
1096 }
1097 if( has_trait( trait_M_SKIN3 ) ) {
1098 // Spores happen!
1099 if( g->m.has_flag_ter_or_furn( "FUNGUS", pos() ) ) {
1100 if( get_fatigue() >= 0 ) {
1101 mod_fatigue( -5 ); // Local guides need less sleep on fungal soil
1102 }
1103 if( calendar::once_every( 1_hours ) ) {
1104 spores(); // spawn some P O O F Y B O I S
1105 }
1106 }
1107 }
1108 if( has_trait( trait_WATERSLEEP ) ) {
1109 mod_fatigue( -3 ); // Fish sleep less in water
1110 }
1111 }
1112
1113 // Check mutation category strengths to see if we're mutated enough to get a dream
1114 std::string highcat = get_highest_category();
1115 int highest = mutation_category_level[highcat];
1116
1117 // Determine the strength of effects or dreams based upon category strength
1118 int strength = 0; // Category too weak for any effect or dream
1119 if( crossed_threshold() ) {
1120 strength = 4; // Post-human.
1121 } else if( highest >= 20 && highest < 35 ) {
1122 strength = 1; // Low strength
1123 } else if( highest >= 35 && highest < 50 ) {
1124 strength = 2; // Medium strength
1125 } else if( highest >= 50 ) {
1126 strength = 3; // High strength
1127 }
1128
1129 // Get a dream if category strength is high enough.
1130 if( strength != 0 ) {
1131 //Once every 6 / 3 / 2 hours, with a bit of randomness
1132 if( calendar::once_every( 6_hours / strength ) && one_in( 3 ) ) {
1133 // Select a dream
1134 std::string dream = dreams::get_random_for_category( highcat, strength );
1135 if( !dream.empty() ) {
1137 }
1138 // Mycus folks upgrade in their sleep.
1139 if( has_trait( trait_THRESH_MYCUS ) ) {
1140 if( one_in( 8 ) ) {
1141 mutate_category( "MYCUS" );
1142 mod_stored_nutr( 10 );
1143 mod_thirst( 10 );
1144 mod_fatigue( 5 );
1145 }
1146 }
1147 }
1148 }
1149
1150 bool woke_up = false;
1151 int tirednessVal = rng( 5, 200 ) + rng( 0, std::abs( get_fatigue() * 2 * 5 ) );
1152 if( !is_blind() && !has_effect( effect_narcosis ) ) {
1153 if( !has_trait(
1154 trait_SEESLEEP ) ) { // People who can see while sleeping are acclimated to the light.
1156 // So you can too sleep through noon
1157 if( ( tirednessVal * 1.25 ) < g->m.ambient_light_at( pos() ) && ( get_fatigue() < 10 ||
1158 one_in( get_fatigue() / 2 ) ) ) {
1159 add_msg_if_player( _( "It's too bright to sleep." ) );
1160 // Set ourselves up for removal
1161 it.set_duration( 0_turns );
1162 woke_up = true;
1163 }
1164 // Ursine hibernators would likely do so indoors. Plants, though, might be in the sun.
1165 } else if( has_trait( trait_HIBERNATE ) ) {
1166 if( ( tirednessVal * 5 ) < g->m.ambient_light_at( pos() ) && ( get_fatigue() < 10 ||
1167 one_in( get_fatigue() / 2 ) ) ) {
1168 add_msg_if_player( _( "It's too bright to sleep." ) );
1169 // Set ourselves up for removal
1170 it.set_duration( 0_turns );
1171 woke_up = true;
1172 }
1173 } else if( tirednessVal < g->m.ambient_light_at( pos() ) && ( get_fatigue() < 10 ||
1174 one_in( get_fatigue() / 2 ) ) ) {
1175 add_msg_if_player( _( "It's too bright to sleep." ) );
1176 // Set ourselves up for removal
1177 it.set_duration( 0_turns );
1178 woke_up = true;
1179 }
1180 } else if( has_active_mutation( trait_SEESLEEP ) ) {
1181 Creature *hostile_critter = g->is_hostile_very_close();
1182 if( hostile_critter != nullptr ) {
1183 add_msg_if_player( _( "You see %s approaching!" ),
1184 hostile_critter->disp_name() );
1185 it.set_duration( 0_turns );
1186 woke_up = true;
1187 }
1188 }
1189 }
1190
1191 // Have we already woken up?
1192 if( !woke_up && !has_effect( effect_narcosis ) ) {
1193 // Cold or heat may wake you up.
1194 // Player will sleep through cold or heat if fatigued enough
1195 for( const body_part bp : all_body_parts ) {
1196 if( temp_cur[bp] < BODYTEMP_VERY_COLD - get_fatigue() / 2 ) {
1197 if( one_in( 30000 ) ) {
1198 add_msg_if_player( _( "You toss and turn trying to keep warm." ) );
1199 }
1200 if( temp_cur[bp] < BODYTEMP_FREEZING - get_fatigue() / 2 ||
1201 one_in( temp_cur[bp] * 6 + 30000 ) ) {
1202 add_msg_if_player( m_bad, _( "It's too cold to sleep." ) );
1203 // Set ourselves up for removal
1204 it.set_duration( 0_turns );
1205 woke_up = true;
1206 break;
1207 }
1208 } else if( temp_cur[bp] > BODYTEMP_VERY_HOT + get_fatigue() / 2 ) {
1209 if( one_in( 30000 ) ) {
1210 add_msg_if_player( _( "You toss and turn in the heat." ) );
1211 }
1212 if( temp_cur[bp] > BODYTEMP_SCORCHING + get_fatigue() / 2 ||
1213 one_in( 90000 - temp_cur[bp] ) ) {
1214 add_msg_if_player( m_bad, _( "It's too hot to sleep." ) );
1215 // Set ourselves up for removal
1216 it.set_duration( 0_turns );
1217 woke_up = true;
1218 break;
1219 }
1220 }
1221 }
1223 one_in( 43200 ) && is_player() ) ) {
1224 if( one_in( 2 ) ) {
1225 sound_hallu();
1226 } else {
1227 int max_count = rng( 1, 3 );
1228 int count = 0;
1229 for( const tripoint &mp : g->m.points_in_radius( pos(), 1 ) ) {
1230 if( mp == pos() ) {
1231 continue;
1232 }
1233 if( g->m.has_flag( "FLAT", mp ) &&
1234 g->m.pl_sees( mp, 2 ) ) {
1235 g->spawn_hallucination( mp );
1236 if( ++count > max_count ) {
1237 break;
1238 }
1239 }
1240 }
1241 }
1242 it.set_duration( 0_turns );
1243 woke_up = true;
1244 }
1245 }
1246
1247 // A bit of a hack: check if we are about to wake up for any reason, including regular
1248 // timing out of sleep
1249 if( dur == 1_turns || woke_up ) {
1250 wake_up();
1251 }
1252 } else if( id == effect_alarm_clock ) {
1253 if( in_sleep_state() ) {
1254 const bool asleep = has_effect( effect_sleep );
1255 if( has_bionic( bio_watch ) ) {
1256 if( dur == 1_turns ) {
1257 if( !asleep ) {
1258 add_msg_if_player( _( "Your internal chronometer went off and you haven't slept a wink." ) );
1260 } else {
1261 // Secure the flag before wake_up() clears the effect
1262 bool slept_through = has_effect( effect_slept_through_alarm );
1263 wake_up();
1264 if( slept_through ) {
1265 add_msg_if_player( _( "Your internal chronometer finally wakes you up." ) );
1266 } else {
1267 add_msg_if_player( _( "Your internal chronometer wakes you up." ) );
1268 }
1269 }
1270 }
1271 } else {
1272 if( asleep && dur == 1_turns ) {
1275 }
1276 // 10 minute automatic snooze
1277 it.mod_duration( 10_minutes );
1278 } else if( dur == 2_turns ) {
1279 // let the sound code handle the wake-up part
1280 sounds::sound( pos(), 16, sounds::sound_t::alarm, _( "beep-beep-beep!" ), false, "tool",
1281 "alarm_clock" );
1282 }
1283 }
1284 } else {
1285 if( dur == 1_turns ) {
1286 if( is_avatar() && has_alarm_clock() ) {
1287 sounds::sound( pos(), 16, sounds::sound_t::alarm, _( "beep-beep-beep!" ), false, "tool",
1288 "alarm_clock" );
1289 const std::string alarm = _( "Your alarm is going off." );
1290 g->cancel_activity_or_ignore_query( distraction_type::alert, alarm );
1291 add_msg( _( "Your alarm went off." ) );
1292 }
1293 }
1294 }
1295 } else if( id == effect_mending ) {
1296 if( !is_limb_broken( convert_bp( bp ) ) ) {
1297 it.set_duration( 0_turns );
1298 }
1299 } else if( id == effect_disabled ) {
1300 if( !is_limb_broken( convert_bp( bp ) ) ) {
1302 }
1303 } else if( id == effect_panacea ) {
1304 // restore health all body parts, dramatically reduce pain
1305 healall( 1 );
1306 mod_pain( -10 );
1307 }
1308}
bool has_psy_protection(const Character &c, int partial_chance)
Returns true if the player has a psyshield artifact, or sometimes if wearing tinfoil.
void mutate_category(const std::string &mut_cat)
Picks a random valid mutation in a category and mutate_towards() it.
Definition: mutation.cpp:1019
void sound_hallu()
Creates an auditory hallucination.
Definition: suffer.cpp:1775
void wake_up()
Removes "sleep" and "lying_down".
Definition: character.cpp:7576
int posz() const override
Definition: character.h:803
virtual void mod_per_bonus(int nper)
Definition: character.cpp:4208
virtual void mod_dex_bonus(int ndex)
Definition: character.cpp:4203
void mutate()
Picks a random valid mutation and gives it to the Character, possibly removing/changing others along ...
Definition: mutation.cpp:820
bool crossed_threshold() const
Returns true if the player has crossed a mutation threshold Player can only cross one mutation thresh...
Definition: character.cpp:8718
bool is_blind() const
Returns true if the player isn't able to see.
Definition: character.cpp:6274
bool has_alarm_clock() const
Returns true if the player or their vehicle has an alarm clock.
Definition: character.cpp:722
virtual void mod_str_bonus(int nstr)
Definition: character.cpp:4198
std::string get_highest_category() const
Returns the highest mutation category.
Definition: character.cpp:7840
virtual void mod_stored_nutr(int nnutr)
Definition: character.cpp:4328
void hurtall(int dam, Creature *source, bool disturb=true)
Hurts all body parts for dam, no armor reduction.
Definition: character.cpp:8663
int get_speed() const override
Definition: character.cpp:4148
bool irradiate(float rads, bool bypass=false)
Handles mitigation and application of radiation.
Definition: suffer.cpp:1601
virtual void mod_int_bonus(int nint)
Definition: character.cpp:4213
virtual int get_num_blocks_bonus() const
Definition: creature.cpp:1488
virtual void set_num_blocks_bonus(int nblocks)
Definition: creature.cpp:1765
void set_moves(int nmoves)
Definition: creature.cpp:1452
static MonsterGroupResult GetResultFromGroup(const mongroup_id &group, int *quantity=nullptr)
Definition: mongroup.cpp:98
void set_duration(const time_duration &dur, bool alert=false)
Sets the duration, capping at max_duration if it exists.
Definition: effect.cpp:805
int mod_intensity(int mod, bool alert=false)
Modify intensity of effect capped by range [1..max_intensity].
Definition: effect.cpp:886
void pump_events()
Resize & refresh if necessary, process all pending window events, and ignore keypresses.
bool has_effect_when_carried(art_effect_passive effect) const
Does the item provide the artifact effect when it is carried?
Definition: item.cpp:9786
bool has_effect_when_wielded(art_effect_passive effect) const
Does the item provide the artifact effect when it is wielded?
Definition: item.cpp:9768
static const ma_buff * from_effect(const effect &eff)
int get_grab_strength() const
Definition: monster.cpp:2031
Definition: player.h:84
@ AEP_EVIL
Definition: enums.h:127
@ AEP_SCHIZO
Definition: enums.h:128
@ dies_from_asthma_attack
@ dermatik_eggs_hatch
@ teleglow_teleports
field_type_id fd_tindalos_rift
Definition: field_type.cpp:387
input_manager inp_mngr
Definition: input.cpp:109
furn_id f_rubble_rock
Definition: mapdata.cpp:1099
const morale_type MORALE_FEELING_BAD("morale_feeling_bad")
double vomit_mod(const Character &ch)
Returns the modifier value used for vomiting effects.
bool roll_can_sleep(Character &who)
Checked each turn during "lying_down", returns true if the avatar falls asleep.
constexpr size_t count()
Definition: fmtlib_core.h:1073
std::string get_random_for_category(const std::string &cat, int strength)
Returns a random dream description that matches given category and strength.
Definition: sounds.h:92
static const trait_id trait_M_SKIN3("M_SKIN3")
static const efftype_id effect_bloodworms("bloodworms")
static const efftype_id effect_downed("downed")
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_blind("blind")
static const efftype_id effect_datura("datura")
static const efftype_id effect_teleglow("teleglow")
static const efftype_id effect_dermatik("dermatik")
static const efftype_id effect_bleed("bleed")
static const efftype_id effect_narcosis("narcosis")
static const efftype_id effect_adrenaline("adrenaline")
static const efftype_id effect_infected("infected")
static const efftype_id effect_cold("cold")
static const efftype_id effect_attention("attention")
static const efftype_id effect_recover("recover")
static const efftype_id effect_asthma("asthma")
static const efftype_id effect_antibiotic("antibiotic")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static void eff_fun_bloated(player &u, effect &it)
static const efftype_id effect_hallu("hallu")
static void eff_fun_cold(player &u, effect &it)
static const efftype_id effect_bite("bite")
static const mtype_id mon_dermatik_larva("mon_dermatik_larva")
static const trait_id trait_THRESH_MYCUS("THRESH_MYCUS")
static const efftype_id effect_tapeworm("tapeworm")
static const efftype_id effect_boomered("boomered")
static const trait_id trait_HIBERNATE("HIBERNATE")
static const trait_id trait_SEESLEEP("SEESLEEP")
static const efftype_id effect_hot("hot")
static const mongroup_id GROUP_NETHER("GROUP_NETHER")
static void eff_fun_hot(player &u, effect &it)
static void eff_fun_bleed(player &u, effect &it)
static const efftype_id effect_spores("spores")
static const efftype_id effect_evil("evil")
static const trait_id trait_INFRESIST("INFRESIST")
static const efftype_id effect_grabbing("grabbing")
static const efftype_id effect_weak_antibiotic("weak_antibiotic")
static void eff_fun_fungus(player &u, effect &it)
static const efftype_id effect_panacea("panacea")
static const efftype_id effect_visuals("visuals")
static const efftype_id effect_dazed("dazed")
static void eff_fun_toxin_buildup(player &u, effect &it)
static void eff_fun_spores(player &u, effect &it)
static const bionic_id bio_watch("bio_watch")
static const efftype_id effect_paincysts("paincysts")
static const efftype_id effect_toxin_buildup("toxin_buildup")
static const efftype_id effect_sleep("sleep")
static const efftype_id effect_bloated("bloated")
static void eff_fun_mutating(player &u, effect &it)
static const efftype_id effect_fearparalyze("fearparalyze")
static const efftype_id effect_strong_antibiotic("strong_antibiotic")
static const trait_id trait_CHLOROMORPH("CHLOROMORPH")
static const trait_id trait_WATERSLEEP("WATERSLEEP")
static const efftype_id effect_nausea("nausea")
static const efftype_id effect_rat("rat")
static void eff_fun_frostbite(player &u, effect &it)
static void eff_fun_onfire(player &u, effect &it)
static const efftype_id effect_lying_down("lying_down")
static const efftype_id effect_slept_through_alarm("slept_through_alarm")
static void eff_fun_rat(player &u, effect &it)
static const efftype_id effect_mutating("mutating")
static void eff_fun_hallu(player &u, effect &it)
static const efftype_id effect_formication("formication")
static const trait_id trait_HEAVYSLEEPER2("HEAVYSLEEPER2")
static const efftype_id effect_mending("mending")
static const efftype_id effect_grabbed("grabbed")
static const efftype_id effect_disabled("disabled")
static const efftype_id effect_alarm_clock("alarm_clock")
static const trait_id trait_NOPAIN("NOPAIN")
static const trait_id trait_SCHIZOPHRENIC("SCHIZOPHRENIC")
static const efftype_id effect_brainworms("brainworms")
static const efftype_id effect_onfire("onfire")
static const efftype_id effect_frostbite("frostbite")
bool one_turn_in(const time_duration &duration)
Definition: rng.cpp:70
mtype_id name
Definition: mongroup.h:53

References _, activity, sounds::activity, Creature::add_effect(), add_miss_reason(), add_morale(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), AEP_EVIL, AEP_SCHIZO, sounds::alarm, alert, all_body_parts, apply_damage(), Creature::as_player(), bio_watch, body_part_name(), body_part_name_accusative(), BODYTEMP_FREEZING, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, bp_torso, convert_bp(), detail::count(), crossed_threshold(), dermatik_eggs_hatch, dies_from_asthma_attack, dies_from_drug_overdose, dies_of_infection, Creature::disp_name(), eff_fun_bleed(), eff_fun_bloated(), eff_fun_cold(), eff_fun_frostbite(), eff_fun_fungus(), eff_fun_hallu(), eff_fun_hot(), eff_fun_mutating(), eff_fun_onfire(), eff_fun_rat(), eff_fun_spores(), eff_fun_toxin_buildup(), effect_adrenaline, effect_alarm_clock, effect_antibiotic, effect_asthma, effect_attention, effect_bite, effect_bleed, effect_blind, effect_bloated, effect_bloodworms, effect_boomered, effect_brainworms, effect_cold, effect_datura, effect_dazed, effect_dermatik, effect_disabled, effect_downed, effect_evil, effect_fearparalyze, effect_formication, effect_frostbite, effect_fungus, effect_grabbed, effect_grabbing, effect_hallu, effect_hot, effect_infected, effect_lying_down, effect_mending, effect_mutating, effect_narcosis, effect_nausea, effect_onfire, effect_paincysts, effect_panacea, effect_rat, effect_recover, effect_sleep, effect_slept_through_alarm, effect_spores, effect_strong_antibiotic, effect_tapeworm, effect_teleglow, effect_toxin_buildup, effect_visuals, effect_weak_antibiotic, f_rubble_rock, fall_asleep(), fd_tindalos_rift, focus_pool, ma_buff::from_effect(), g, effect::get_bp(), effect::get_duration(), Creature::get_effect_dur(), get_fatigue(), monster::get_grab_strength(), get_healthy(), get_highest_category(), effect::get_id(), get_int(), effect::get_intensity(), Creature::get_num_blocks_bonus(), dreams::get_random_for_category(), get_sleep_deprivation(), get_speed(), get_stim(), get_stored_kcal(), get_thirst(), get_weather(), getID(), MonsterGroupManager::GetResultFromGroup(), GROUP_NETHER, harmless, has_active_mutation(), has_alarm_clock(), has_artifact_with(), has_bionic(), Creature::has_effect(), item::has_effect_when_carried(), item::has_effect_when_wielded(), has_psy_protection(), has_trait(), healall(), hostile_spotted_far, hurtall(), id, in_sleep_state(), inp_mngr, irradiate(), Creature::is_avatar(), is_blind(), is_limb_broken(), Creature::is_npc(), Creature::is_player(), light, m_bad, m_good, m_info, m_warning, max_stored_kcal(), mod_dex_bonus(), effect::mod_duration(), mod_fatigue(), mod_healthy_mod(), mod_int_bonus(), effect::mod_intensity(), mod_pain(), mod_per_bonus(), mod_stim(), mod_stored_kcal(), mod_stored_nutr(), mod_str_bonus(), mod_thirst(), mon_dermatik_larva, MORALE_FEELING_BAD, Creature::moves, mutate(), mutate_category(), mutation_category_level, name, MonsterGroupResult::name, num_bp, calendar::once_every(), one_in(), one_turn_in(), pos(), posx(), posy(), posz(), primary_weapon(), input_manager::pump_events(), snippet_library::random_from_category(), Creature::remove_effect(), rng(), character_funcs::roll_can_sleep(), effect::set_duration(), set_fatigue(), Creature::set_moves(), Creature::set_num_blocks_bonus(), Creature::set_part_hp_cur(), player_activity::set_to_null(), SNIPPET, sounds::sound(), sound_hallu(), spores(), str_max, teleglow_teleports, teleport::teleport(), temp_cur, body_part_type::token, trait_CHLOROMORPH, trait_HEAVYSLEEPER2, trait_HIBERNATE, trait_INFRESIST, trait_M_IMMUNE, trait_M_SKIN3, trait_NOPAIN, trait_SCHIZOPHRENIC, trait_SEESLEEP, trait_THRESH_MYCUS, trait_WATERSLEEP, turgid, vomit(), character_effects::vomit_mod(), wake_up(), worn, tripoint::x, x_in_y(), and tripoint::y.

Referenced by process_one_effect().

◆ has_active_bionic()

bool Character::has_active_bionic ( const bionic_id b) const

Returns true if the player has the entered bionic id and it is powered on.

Definition at line 1824 of file character.cpp.

1825{
1826 for( const bionic &i : *my_bionics ) {
1827 if( i.id == b ) {
1828 return ( i.powered && i.incapacitated_time == 0_turns );
1829 }
1830 }
1831 return false;
1832}

References b, and my_bionics.

Referenced by absorb_hit(), activate_bionic(), active_light(), adjust_for_focus(), attack_cost(), basic_symbol_color(), burn_move_stamina(), character_martial_arts::can_arm_block(), can_feed_furnace_with(), character_martial_arts::can_leg_block(), comestible_inventory_preset::comestible_inventory_preset(), crit_chance(), avatar::do_read(), do_skill_rust(), game::do_turn(), draw_bionics_titlebar(), draw_skills_tab(), iuse::ehandcuffs(), npc::finish_read(), get_env_resist(), get_hit_weapon(), ranged::gunmode_checks_weapon(), game::handle_action(), has_fire(), has_nv(), hearing_ability(), impact(), in_climate_control(), is_blind(), is_deaf(), is_immune_damage(), is_immune_field(), ma_requirements::is_valid_character(), game::item_action_menu(), trapfunc::ledge(), melee_attack(), melee_special_effects(), modify_morale(), game::monmove(), mut_cbm_encumb(), on_hit(), game::on_move_effects(), perform_technique(), character_martial_arts::pick_style(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), map::player_in_field(), process_items(), character_funcs::rate_sleep_spot(), recalc_sight_limits(), npc::recharge_cbm(), game::remoteveh(), reset_stats(), mattack::riotbot(), roll_bash_damage(), character_funcs::roll_can_sleep(), roll_cut_damage(), roll_stab_damage(), run_cost(), character_funcs::search_surroundings(), sees_with_specials(), game::setremoteveh(), iuse::solarpack(), ranged::throw_item(), throw_range(), avatar_funcs::try_to_sleep(), character_funcs::try_uncanny_dodge(), update_health(), update_needs(), update_stamina(), use_charges(), use_fire(), and npc::wants_to_recharge_cbm().

◆ has_active_item()

bool Character::has_active_item ( const itype_id id) const

Whether the player carries an active item of the given item type.

Definition at line 2509 of file character.cpp.

2510{
2511 return has_item_with( [id]( const item & it ) {
2512 return it.active && it.typeId() == id;
2513 } );
2514}

References item::active, visitable< Character >::has_item_with(), and item::typeId().

Referenced by deactivate_bionic(), game::handle_action(), iuse::mp3(), game::remoteveh(), and game::setremoteveh().

◆ has_active_mutation()

◆ has_activity() [1/2]

bool Character::has_activity ( const activity_id type) const

◆ has_activity() [2/2]

bool Character::has_activity ( const std::vector< activity_id > &  types) const

Check if player currently has any of the given activities.

Definition at line 9229 of file character.cpp.

9230{
9231 return std::find( types.begin(), types.end(), activity.id() ) != types.end();
9232}
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)

References activity, detail::find(), and player_activity::id().

◆ has_addiction()

bool Character::has_addiction ( add_type  type) const

Returns true if the player has an addiction of the specified type.

Definition at line 2007 of file suffer.cpp.

2008{
2009 return std::any_of( addictions.begin(), addictions.end(),
2010 [type]( const addiction & ad ) {
2011 return ad.type == type && ad.intensity >= MIN_ADDICTION_LEVEL;
2012 } );
2013}

References addictions, and type.

Referenced by character_funcs::rate_sleep_spot().

◆ has_alarm_clock()

bool Character::has_alarm_clock ( ) const

Returns true if the player or their vehicle has an alarm clock.

Definition at line 722 of file character.cpp.

723{
724 map &here = get_map();
725 return ( has_item_with_flag( "ALARMCLOCK", true ) ||
726 ( here.veh_at( pos() ) &&
727 !empty( here.veh_at( pos() )->vehicle().get_avail_parts( "ALARMCLOCK" ) ) ) ||
729}
static const bionic_id bio_watch("bio_watch")
bool has_item_with_flag(const std::string &flag, bool need_charges=false) const
Definition: character.cpp:9586

References bio_watch, get_map(), has_bionic(), has_item_with_flag(), pos(), map::veh_at(), and vehicle.

Referenced by hardcoded_effects(), sleep(), and wait().

◆ has_any_bionic()

bool Character::has_any_bionic ( ) const

Returns true if the player has any bionic.

Definition at line 1834 of file character.cpp.

1835{
1836 return !get_bionics().empty();
1837}

References get_bionics().

Referenced by mattack::nurse_operate().

◆ has_artifact_with()

bool Character::has_artifact_with ( art_effect_passive  effect) const
virtual

Reimplemented in npc.

Definition at line 3212 of file character.cpp.

3213{
3214 for( const item *weapon : wielded_items() ) {
3215 if( weapon->has_effect_when_wielded( effect ) ) {
3216 return true;
3217 }
3218 }
3219 for( auto &i : worn ) {
3220 if( i.has_effect_when_worn( effect ) ) {
3221 return true;
3222 }
3223 }
3224 return has_item_with( [effect]( const item & it ) {
3225 return it.has_effect_when_carried( effect );
3226 } );
3227}
std::vector< item * > wielded_items()
Returns all equipped items that require a limb to be held.
Definition: melee.cpp:185

References item::has_effect_when_carried(), visitable< Character >::has_item_with(), wielded_items(), and worn.

Referenced by active_light(), basic_symbol_color(), deal_damage(), item::food_info(), hardcoded_effects(), is_immune_damage(), is_invisible(), melee_attack(), map::open_door(), recalc_sight_limits(), recalc_speed_bonus(), suffer_from_artifacts(), suffer_while_awake(), update_health(), game::walk_move(), and weight_capacity().

◆ has_base_trait()

bool Character::has_base_trait ( const trait_id b) const

Returns true if the player has the entered starting trait.

Definition at line 119 of file mutation.cpp.

120{
121 // Look only at base traits
122 return my_traits.find( b ) != my_traits.end();
123}

References b, and my_traits.

Referenced by build_mut_dependency_map(), do_purify(), wish_mutate_callback::key(), mutate_towards(), old_mutate(), iuse::purify_iv(), iuse::purify_smart(), remove_mutation(), detail::show_mutations_ui_internal(), and debug_menu::wishmutate().

◆ has_bionic()

bool Character::has_bionic ( const bionic_id b) const

Returns true if the player has the entered bionic id.

Definition at line 1814 of file character.cpp.

1815{
1816 for( const bionic_id &bid : get_bionics() ) {
1817 if( bid == b ) {
1818 return true;
1819 }
1820 }
1821 return false;
1822}

References b, and get_bionics().

Referenced by npc::activate_bionic_by_id(), add_bionic(), iexamine::autodoc(), autodoc_internal(), bionics_install_failure(), talk_trial::calc_chance(), calc_needs_rates(), character_martial_arts::can_arm_block(), character_martial_arts::can_leg_block(), npc::can_read(), can_uninstall_bionic(), install_bionic_actor::can_use(), item::color_in_inventory(), consume_effects(), consume_med(), activity_handlers::cracking_do_turn(), deactivate_bionic(), npc::deactivate_bionic_by_id(), draw_env_compact(), draw_speed_tab(), draw_time_classic(), eat(), iuse::einktabletpc(), iexamine::fireplace(), item::food_info(), avatar::get_book_reader(), bionic_install_preset::get_denial(), bionic_install_surgeon_preset::get_denial(), get_temp(), ranged::get_weapon_dispersion(), hardcoded_effects(), has_alarm_clock(), has_enough_anesth(), has_fire(), has_watch(), is_immune_effect(), player::load(), game::on_move_effects(), activity_handlers::operation_do_turn(), overmap_sight_range(), iexamine::pay_gas(), sounds::process_sound_markers(), read_speed(), recalc_sight_limits(), recalc_speed_bonus(), iuse::robotcontrol(), roll_cut_damage(), roll_stab_damage(), run_cost(), iexamine::safe(), conditional_t< T >::set_has_bionics(), sight_impaired(), suffer_from_asthma(), suffer_from_bad_bionics(), suffer_from_radiation(), suffer_from_sunburn(), suffer_while_underwater(), try_start_hacking(), update_bodytemp(), consume_drug_iuse::use(), npc::use_bionic_by_id(), game::use_computer(), use_fire(), volume_capacity_reduced_by(), avatar::wake_up(), game::walk_move(), and will_eat().

◆ has_bionics()

bool Character::has_bionics ( ) const

Whether character has any bionics installed.

Definition at line 2694 of file bionics.cpp.

2695{
2696 return !my_bionics->empty() || has_max_power();
2697}

References has_max_power(), and my_bionics.

Referenced by conditional_t< T >::set_has_bionics().

◆ has_charges()

bool Character::has_charges ( const itype_id it,
int  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
) const

Definition at line 9603 of file character.cpp.

9605{
9606 if( it == itype_fire || it == itype_apparatus ) {
9607 return has_fire( quantity );
9608 }
9609 if( it == itype_UPS && is_mounted() &&
9610 mounted_creature.get()->has_flag( MF_RIDEABLE_MECH ) ) {
9611 auto mons = mounted_creature.get();
9612 return quantity <= mons->battery_item->ammo_remaining();
9613 }
9614 if( it == itype_bio_armor ) {
9615 int mod_qty = 0;
9616 float efficiency = 1;
9617 for( const bionic &bio : *my_bionics ) {
9618 if( bio.powered && bio.info().has_flag( flag_BIONIC_ARMOR_INTERFACE ) ) {
9619 efficiency = std::max( efficiency, bio.info().fuel_efficiency );
9620 }
9621 }
9622 if( efficiency == 1 ) {
9623 debugmsg( "Player lacks a bionic armor interface with fuel efficiency field." );
9624 }
9625 mod_qty = quantity / efficiency;
9626 return ( has_power() && get_power_level() >= units::from_kilojoule( mod_qty ) );
9627 }
9628 return charges_of( it, quantity, filter ) == quantity;
9629}
static const itype_id itype_fire("fire")
static const flag_str_id flag_BIONIC_ARMOR_INTERFACE("BIONIC_ARMOR_INTERFACE")
static const itype_id itype_apparatus("apparatus")
bool has_power() const
Definition: character.cpp:1946
bool has_fire(int quantity) const
Definition: character.cpp:9750

References visitable< Character >::charges_of(), debugmsg, flag_BIONIC_ARMOR_INTERFACE, units::from_kilojoule(), get_power_level(), has_fire(), has_power(), is_mounted(), itype_apparatus, itype_bio_armor, itype_fire, itype_UPS, MF_RIDEABLE_MECH, mounted_creature, and my_bionics.

Referenced by iexamine::arcfurnace_empty(), iuse::cable_attach(), can_eat(), iexamine::can_fertilize(), can_reload(), cauterize_actor::can_use(), craft_command::check_item_components_missing(), craft_command::check_tool_components_missing(), consume_charges(), consume_med(), consume_remote_fuel(), player::craft_consume_tools(), iuse::ecig(), activity_handlers::fertilize_plot_do_turn(), find_remote_fuel(), crafting::find_tool_component(), iuse::firecracker_pack(), avatar_funcs::gunmod_add(), ranged::gunmode_checks_weapon(), has_enough_charges(), has_fire(), npc::heal_self(), iexamine::kiln_empty(), npc::move(), iexamine::pay_gas(), avatar_action::reload(), talk_effect_fun_t::set_consume_item(), conditional_t< T >::set_has_items(), talk_effect_fun_t::set_u_sell_item(), smoker_activate(), iuse::smoking(), suffer_from_asthma(), try_consume(), try_start_hacking(), consume_drug_iuse::use(), use_charges_if_avail(), and use_fire().

◆ has_child_flag()

bool Character::has_child_flag ( const trait_id flag) const

Returns true if the player has the entered mutation child flag.

Definition at line 1460 of file mutation.cpp.

1461{
1462 for( const trait_id &elem : flag->replacements ) {
1463 const trait_id &tmp = elem;
1464 if( has_trait( tmp ) || has_child_flag( tmp ) ) {
1465 return true;
1466 }
1467 }
1468 return false;
1469}
bool has_child_flag(const trait_id &flag) const
Returns true if the player has the entered mutation child flag.
Definition: mutation.cpp:1460

References has_child_flag(), has_trait(), and mutation_branch::replacements.

Referenced by has_child_flag(), mutate_towards(), mutation_ok(), and remove_child_flag().

◆ has_destination()

◆ has_destination_activity()

bool Character::has_destination_activity ( ) const

◆ has_distant_destination()

bool Character::has_distant_destination ( ) const

Definition at line 10501 of file character.cpp.

10502{
10505}
static const activity_id ACT_TRAVELLING("ACT_TRAVELLING")
std::vector< tripoint_abs_omt > omt_path
Route for overmap scale traveling.
Definition: character.h:1839

References ACT_TRAVELLING, get_destination_activity(), has_destination(), player_activity::id(), player_activity::is_null(), and omt_path.

Referenced by game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), and game::do_turn().

◆ has_enough_anesth()

bool Character::has_enough_anesth ( const itype cbm,
player patient 
)

Has enough anesthetic for surgery.

Definition at line 1901 of file bionics.cpp.

1902{
1903 if( !cbm->bionic ) {
1904 debugmsg( "has_enough_anesth( const itype *cbm ): %s is not a bionic", cbm->get_id() );
1905 return false;
1906 }
1907
1910 return true;
1911 }
1912
1913 const int weight = 7;
1914 const requirement_data req_anesth = *requirement_id( "anesthetic" ) *
1915 cbm->bionic->difficulty * 2 * weight;
1916
1918}
static const bionic_id bio_painkiller("bio_painkiller")
static const trait_id trait_DEBUG_BIONICS("DEBUG_BIONICS")
static const trait_id trait_NOPAIN("NOPAIN")
bool is_crafting_component(const item &component)
Default filter for crafting component searches.
Definition: item.h:2265
cata::value_ptr< islot_bionic > bionic
Definition: itype.h:831
bool can_make_with_inventory(const inventory &crafting_inv, const std::function< bool(const item &)> &filter, int batch=1, cost_adjustment=cost_adjustment::none) const
Returns true if the requirements are fufilled by the filtered inventory.
string_id< requirement_data > requirement_id
Definition: type_id.h:146

References bio_painkiller, itype::bionic, requirement_data::can_make_with_inventory(), crafting_inventory(), debugmsg, itype::get_id(), has_bionic(), has_trait(), is_crafting_component(), trait_DEBUG_BIONICS, and trait_NOPAIN.

Referenced by bionic_install_preset::get_denial(), and bionic_uninstall_preset::get_denial().

◆ has_enough_charges()

bool Character::has_enough_charges ( const item it,
bool  show_msg 
) const

Has the item enough charges to invoke its use function? Also checks if UPS from this player is used instead of item charges.

Definition at line 7358 of file character.cpp.

7359{
7360 if( !it.is_tool() || !it.ammo_required() ) {
7361 return true;
7362 }
7363 if( it.is_power_armor() ) {
7364 if( ( character_funcs::can_interface_armor( *this ) &&
7367 it.ammo_sufficient() ) {
7368 return true;
7369 }
7370
7371 if( show_msg ) {
7372 if( it.has_flag( flag_USE_UPS ) ) {
7374 vgettext( "Your %s needs %d charge, from some UPS or a Bionic Power Interface.",
7375 "Your %s needs %d charges, from some UPS or a Bionic Power Interface.",
7376 it.ammo_required() ),
7377 it.tname(), it.ammo_required() );
7378 } else {
7380 vgettext( "Your %s needs %d charge, from a Bionic Power Interface.",
7381 "Your %s needs %d charges, from a Bionic Power Interface.",
7382 it.ammo_required() ),
7383 it.tname(), it.ammo_required() );
7384 }
7385 }
7386 return false;
7387 }
7388 if( it.has_flag( flag_USE_UPS ) ) {
7389 if( has_charges( itype_UPS, it.ammo_required() ) || it.ammo_sufficient() ) {
7390 return true;
7391 }
7392 if( show_msg ) {
7394 vgettext( "Your %s needs %d charge from some UPS.",
7395 "Your %s needs %d charges from some UPS.",
7396 it.ammo_required() ),
7397 it.tname(), it.ammo_required() );
7398 }
7399 return false;
7400 } else if( !it.ammo_sufficient() ) {
7401 if( show_msg ) {
7403 vgettext( "Your %s has %d charge but needs %d.",
7404 "Your %s has %d charges but needs %d.",
7405 it.ammo_remaining() ),
7406 it.tname(), it.ammo_remaining(), it.ammo_required() );
7407 }
7408 return false;
7409 }
7410 return true;
7411}
bool ammo_sufficient(int qty=1) const
Check if sufficient ammo is loaded for given number of uses.
Definition: item.cpp:7492

References Creature::add_msg_if_player(), item::ammo_remaining(), item::ammo_required(), item::ammo_sufficient(), character_funcs::can_interface_armor(), flag_USE_UPS(), has_charges(), item::has_flag(), item::is_power_armor(), item::is_tool(), itype_bio_armor, itype_UPS, m_info, item::tname(), and vgettext().

Referenced by activatable_inventory_preset::get_denial(), invoke_item(), iuse::jackhammer(), and iuse::note_bionics().

◆ has_fire()

bool Character::has_fire ( int  quantity) const

Definition at line 9750 of file character.cpp.

9751{
9752 // TODO: Replace this with a "tool produces fire" flag.
9753
9754 if( get_map().has_nearby_fire( pos() ) ) {
9755 return true;
9756 } else if( has_item_with_flag( "FIRE" ) ) {
9757 return true;
9758 } else if( has_item_with_flag( "FIRESTARTER" ) ) {
9759 auto firestarters = all_items_with_flag( "FIRESTARTER" );
9760 for( auto &i : firestarters ) {
9761 if( !i->type->can_have_charges() ) {
9762 const use_function *usef = i->type->get_use( "firestarter" );
9763 if( !usef ) {
9764 debugmsg( "failed to get use func 'firestarter' for item '%s'", i->typeId().c_str() );
9765 continue;
9766 }
9767 const firestarter_actor *actor = dynamic_cast<const firestarter_actor *>( usef->get_actor_ptr() );
9768 if( actor->can_use( *this->as_character(), *i, false, tripoint_zero ).success() ) {
9769 return true;
9770 }
9771 } else if( has_charges( i->typeId(), quantity ) ) {
9772 return true;
9773 }
9774 }
9775 } else if( has_active_bionic( bio_tools ) && get_power_level() > quantity * 5_kJ ) {
9776 return true;
9777 } else if( has_bionic( bio_lighter ) && get_power_level() > quantity * 5_kJ ) {
9778 return true;
9779 } else if( has_bionic( bio_laser ) && get_power_level() > quantity * 5_kJ ) {
9780 return true;
9781 } else if( is_npc() ) {
9782 // HACK: A hack to make NPCs use their Molotovs
9783 return true;
9784 }
9785 return false;
9786}
static const bionic_id bio_lighter("bio_lighter")
static const bionic_id bio_laser("bio_laser")
static const bionic_id bio_tools("bio_tools")
std::vector< const item * > all_items_with_flag(const std::string &flag) const
All items that have the given flag (item::has_flag).
Definition: character.cpp:9596
Starts a fire instantly.
Definition: iuse_actor.h:529
ret_val< bool > can_use(const Character &, const item &, bool, const tripoint &) const override
iuse_actor * get_actor_ptr()
Definition: iuse.h:316

References all_items_with_flag(), bio_laser, bio_lighter, bio_tools, firestarter_actor::can_use(), debugmsg, use_function::get_actor_ptr(), get_map(), get_power_level(), has_active_bionic(), has_bionic(), has_charges(), has_item_with_flag(), Creature::is_npc(), pos(), and tripoint_zero.

Referenced by has_charges(), and symbol_color().

◆ has_grab_break_tec()

bool Character::has_grab_break_tec ( ) const
overridevirtual

Returns true if the player has a grab breaking technique available.

Implements Creature.

Definition at line 1242 of file martialarts.cpp.

1243{
1244 return martial_arts_data->has_grab_break_tec();
1245}

References martial_arts_data.

Referenced by can_use_grab_break_tec(), deal_damage(), and mattack::grab().

◆ has_item_with_flag()

bool Character::has_item_with_flag ( const std::string &  flag,
bool  need_charges = false 
) const

Definition at line 9586 of file character.cpp.

9587{
9588 return has_item_with( [&flag, &need_charges]( const item & it ) {
9589 if( it.is_tool() && need_charges ) {
9590 return it.has_flag( flag ) && it.type->tool->max_charges ? it.charges > 0 : it.has_flag( flag );
9591 }
9592 return it.has_flag( flag );
9593 } );
9594}

References item::has_flag(), visitable< Character >::has_item_with(), and item::is_tool().

Referenced by draw_env_compact(), draw_time_classic(), npc::faction_display(), get_temp(), has_alarm_clock(), has_fire(), has_watch(), loot(), overmap_sight_range(), monexamine::pet_menu(), npc::reach_omt_destination(), and use_fire().

◆ has_mabuff()

bool Character::has_mabuff ( const mabuff_id buff_id) const

Returns true if the player has any martial arts buffs attached.

Definition at line 1235 of file martialarts.cpp.

1236{
1237 return search_ma_buff_effect( *effects, [&id]( const ma_buff & b, const effect & ) {
1238 return b.id == id;
1239 } );
1240}
static bool search_ma_buff_effect(const C &container, F f)

References b, Creature::effects, id, and search_ma_buff_effect().

Referenced by ma_requirements::is_valid_character().

◆ has_max_power()

bool Character::has_max_power ( ) const

Definition at line 1951 of file character.cpp.

1952{
1953 return max_power_level > 0_kJ;
1954}

References max_power_level.

Referenced by bionics_install_failure(), has_bionics(), power_stat(), and suffer_from_bad_bionics().

◆ has_mission_item()

bool Character::has_mission_item ( int  mission_id) const

Definition at line 2524 of file character.cpp.

2525{
2526 return mission_id != -1 && has_item_with( has_mission_item_filter{ mission_id } );
2527}

References visitable< Character >::has_item_with().

◆ has_morale()

bool Character::has_morale ( const morale_type type) const

Definition at line 9104 of file character.cpp.

9105{
9106 return morale->has( type );
9107}

References morale, and type.

Referenced by ranged::fire_gun(), suffer_from_other_mutations(), and iuse::towel_common().

◆ has_morale_to_craft()

bool Character::has_morale_to_craft ( ) const

Definition at line 336 of file crafting.cpp.

337{
338 return get_morale_level() >= -50;
339}
int get_morale_level() const
Definition: character.cpp:9088

References get_morale_level().

Referenced by game::butcher(), veh_interact::cant_do(), and iuse::multicooker().

◆ has_morale_to_read()

bool Character::has_morale_to_read ( ) const

Definition at line 9124 of file character.cpp.

9125{
9126 return get_morale_level() >= -40;
9127}

References get_morale_level().

Referenced by avatar::get_book_reader().

◆ has_nv()

bool Character::has_nv ( )

Returns true if the player has some form of night vision.

Definition at line 3652 of file character.cpp.

3653{
3654 static bool nv = false;
3655
3656 if( !nv_cached ) {
3657 nv_cached = true;
3658 nv = ( worn_with_flag( flag_GNV_EFFECT ) ||
3661 }
3662
3663 return nv;
3664}
static const std::string flag_GNV_EFFECT("GNV_EFFECT")
static const std::string flag_EFFECT_NIGHT_VISION("EFFECT_NIGHT_VISION")
static const bionic_id bio_night_vision("bio_night_vision")

References bio_night_vision, flag_EFFECT_NIGHT_VISION(), flag_GNV_EFFECT(), has_active_bionic(), Creature::has_effect_with_flag(), nv_cached, and worn_with_flag().

Referenced by recalc_sight_limits().

◆ has_opposite_trait()

bool Character::has_opposite_trait ( const trait_id flag) const

Returns true if character has a trait which cancels the entered trait.

Definition at line 9921 of file character.cpp.

9922{
9923 for( const trait_id &i : flag->cancels ) {
9924 if( has_trait( i ) ) {
9925 return true;
9926 }
9927 }
9928 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
9929 for( const trait_id &canceled_trait : mut.first->cancels ) {
9930 if( canceled_trait == flag ) {
9931 return true;
9932 }
9933 }
9934 }
9935 return false;
9936}
std::vector< trait_id > cancels
Definition: mutation.h:262

References mutation_branch::cancels, has_trait(), and my_mutations.

Referenced by known_magic::can_learn_spell(), and newcharacter::has_conflicting_trait().

◆ has_power()

bool Character::has_power ( ) const

◆ has_stashed_activity()

bool Character::has_stashed_activity ( ) const

Definition at line 919 of file character.cpp.

920{
921 return static_cast<bool>( stashed_outbounds_activity );
922}

References stashed_outbounds_activity.

Referenced by npc::move().

◆ has_trait()

bool Character::has_trait ( const trait_id b) const
overridevirtual

Returns true if the player has the entered trait.

Reimplemented from Creature.

Definition at line 101 of file mutation.cpp.

102{
103 return my_mutations.count( b ) || enchantment_cache->get_mutations().count( b );
104}

References b, enchantment_cache, and my_mutations.

Referenced by absorb_hit(), activate_mutation(), add_addiction(), add_bionic(), character_funcs::add_pain_msg(), newcharacter::add_traits(), addict_effect(), adjust_for_focus(), alcohol(), allergy_type(), iuse::anticonvulsant(), iuse::antiparasitic(), apply_damage(), apply_persistent_morale(), monster::attitude(), iexamine::autodoc(), autodoc_internal(), iexamine::bars(), character_funcs::base_comfort_value(), basic_symbol_color(), bionics_pl_skill(), iuse::blech(), iuse::blood_draw(), bloodType(), body_window(), activity_handlers::build_do_turn(), burn_move_stamina(), calc_all_parts_hp(), talk_trial::calc_chance(), character_effects::calc_focus_equilibrium(), calc_needs_rates(), player::can_continue_craft(), can_eat(), can_install_bionics(), spell::can_learn(), can_pick_weight(), veh_interact::can_potentially_install(), npc::can_read(), veh_interact::can_remove_part(), cauterize_actor::can_use(), install_bionic_actor::can_use(), can_wear(), veh_interact::cant_do(), cauterize_actor::cauterize_effect(), iexamine::chainfence(), game::chat(), check_needs_extremes(), game::check_safe_mode_allowed(), game::cleanup_at_end(), item::color_in_inventory(), talk_function::commune_farmfield(), talk_function::companion_mission(), veh_interact::complete_vehicle(), construction_color(), consume_effects(), consume_item(), player::consume_items(), player::consume_tools(), iuse::contacts(), game::control_vehicle(), cough(), player::craft_consume_tools(), crafting_inventory(), player::crafting_success_roll(), avatar::create(), craft_command::create_in_progress_craft(), iuse::datura(), deal_damage(), debug_vision(), mattack::dermatik(), trap::detect_trap(), monster::die(), character_display::disp_info(), avatar::disp_morale(), veh_interact::do_mend(), do_purify(), game::do_turn(), construct::done_vehicle(), overmap_ui::draw_ascii(), draw_limb_health(), overmap_ui::draw_om_sidebar(), draw_speed_tab(), drench(), eat(), eff_fun_spores(), iuse::einktabletpc(), game::extended_description(), fall_damage_mod(), talk_function::field_harvest(), item::final_info(), game::find_or_make_stairs(), character_funcs::fine_detail_vision_mod(), npc::finish_read(), ranged::fire_gun(), floor_warmth(), iexamine::flower_dahlia(), item::food_info(), talk_function::forage_return(), npc::form_opinion(), fun_for(), fungal_effects::fungalize(), dialogue::gen_responses(), character_funcs::get_book_fun_for(), avatar::get_book_reader(), bionic_install_preset::get_denial(), get_dodge(), get_env_resist(), get_face_type(), get_hunger_description(), character_funcs::get_lift_strength(), get_miss_reason(), npc::get_monster_faction(), overmap_ui::get_overmap_neighbors(), get_pain_description(), character_effects::get_pain_penalty(), get_shout_volume(), give_item_to(), avatar_funcs::gunmod_add(), avatar_funcs::gunmod_installation_odds(), game::handle_action(), hardcoded_effects(), hardcoded_mutation_attack(), iexamine::harvest_plant(), has_child_flag(), has_enough_anesth(), newcharacter::has_higher_trait(), newcharacter::has_lower_trait(), has_opposite_trait(), newcharacter::has_same_type_trait(), hearing_ability(), hit_roll(), hurtall(), in_climate_control(), install_bionics(), introduce_into_anesthesia(), irradiate(), character_funcs::is_bp_immune_to(), is_deaf(), item::is_filthy(), character_funcs::is_fun_to_read(), is_immune_damage(), is_immune_effect(), is_immune_field(), is_invisible(), wish_mutate_callback::key(), game::knockback(), talk_function::labor_return(), known_magic::learn_spell(), trapfunc::ledge(), iexamine::ledge(), player::load(), marloss_common(), marloss_prevented(), iuse::meditate(), melee_attack(), mend(), avatar_funcs::mend_item(), iuse::meth(), mod_pain(), modify_morale(), modify_stimulation(), game::mon_info_update(), avatar_action::move(), iuse::multicooker(), mutate(), mutate_category(), mutate_towards(), mutation_chances(), mutation_ok(), iuse::mycus(), old_mutate(), on_hit(), on_hurt(), npc::on_load(), map::open_door(), iexamine::pay_gas(), perform_install(), pick_part_to_heal(), activity_handlers::pickaxe_finish(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), game::place_player(), iuse::plantblech(), player_can_build(), player_can_see_to_build(), map::player_in_field(), iuse::poison(), iuse::portable_game(), practice(), print_health(), game::print_terrain_info(), process_bionic(), process_effects_internal(), item::process_litcig(), process_one_effect(), sounds::process_sound_markers(), process_turn(), iuse::purify_iv(), iuse::purify_smart(), avatar::randomize(), npc::randomize(), character_funcs::rate_sleep_spot(), react_to_felt_pain(), avatar::read(), recalc_sight_limits(), recalc_speed_bonus(), wish_mutate_callback::refresh(), remove_child_flag(), remove_mutation(), reset_stats(), firestarter_actor::resolve_firestarter_use(), iuse::robotcontrol(), talk_trial::roll(), roll_bash_damage(), rooted(), rooted_message(), iexamine::rubble(), run_cost(), npc::say(), talk_function::scavenging_patrol_return(), sees_with_specials(), player::select_item_component(), conditional_t< T >::set_has_any_trait(), conditional_t< T >::set_has_trait(), set_traits(), shout(), iexamine::shrub_marloss(), sight_impaired(), iexamine::sign(), trapfunc::sinkhole(), game::slip_down(), game::start_game(), stumble(), suffer(), suffer_from_addictions(), suffer_from_chemimbalance(), suffer_from_other_mutations(), suffer_from_radiation(), suffer_from_sunburn(), suffer_in_sunlight(), suffer_while_awake(), suffer_while_underwater(), swim_speed(), npc::talk_to_u(), test_crossing_threshold(), npc::time_to_read(), avatar::time_to_read(), avatar_funcs::toolmod_add(), iexamine::trap(), activity_handlers::tree_communion_do_turn(), iexamine::tree_marloss(), try_reject_mutagen(), try_start_hacking(), avatar_funcs::try_steal_from_npc(), avatar_funcs::try_to_sleep(), uninstall_bionic(), update_body(), character_funcs::update_body_wetness(), update_bodytemp(), update_needs(), veh_interact::update_part_requirements(), game::update_stair_monsters(), update_stomach(), consume_drug_iuse::use(), cauterize_actor::use(), enzlave_actor::use(), mutagen_actor::use(), mutagen_iv_actor::use(), game::use_computer(), game::vertical_move(), iuse::vibe(), volume_capacity_reduced_by(), character_effects::vomit_mod(), game::walk_move(), iuse::weed_cake(), weed_msg(), weight_capacity(), weather_effect::wet_player(), will_eat(), and debug_menu::wishmutate().

◆ has_trait_flag()

bool Character::has_trait_flag ( const std::string &  b) const

Returns true if player has a trait with a flag.

Definition at line 106 of file mutation.cpp.

107{
108 // UGLY, SLOW, should be cached as my_mutation_flags or something
109 for( const trait_id &mut : get_mutations() ) {
110 const mutation_branch &mut_data = mut.obj();
111 if( mut_data.flags.count( b ) > 0 ) {
112 return true;
113 }
114 }
115
116 return false;
117}
std::set< std::string > flags
Definition: mutation.h:266

References b, mutation_branch::flags, and get_mutations().

Referenced by consider_butchery(), do_skill_rust(), item::food_info(), mod_rad(), mod_thirst(), practice(), conditional_t< T >::set_has_trait_flag(), spell::spell_fail(), enzlave_actor::use(), and will_eat().

◆ has_two_arms()

bool Character::has_two_arms ( ) const

Returns true if the player has two functioning arms.

Returns true if the character has two functioning arms.

Definition at line 1220 of file character.cpp.

1221{
1222 return get_working_arm_count() >= 2;
1223}

References get_working_arm_count().

Referenced by can_wear(), can_wield(), ranged::gunmode_checks_common(), hardcoded_mutation_attack(), map::player_in_field(), and mattack::riotbot().

◆ has_watch()

bool Character::has_watch ( ) const

Returns true if the player or their vehicle has a watch.

Definition at line 731 of file character.cpp.

732{
733 map &here = get_map();
734 return ( has_item_with_flag( "WATCH", true ) ||
735 ( here.veh_at( pos() ) &&
736 !empty( here.veh_at( pos() )->vehicle().get_avail_parts( "WATCH" ) ) ) ||
738}

References bio_watch, get_map(), has_bionic(), has_item_with_flag(), pos(), map::veh_at(), and vehicle.

Referenced by draw_loc_labels(), draw_time(), draw_time_classic(), game::list_missions(), and wait().

◆ has_weapon()

bool Character::has_weapon ( ) const
overridevirtual

Implements Creature.

Definition at line 10371 of file character.cpp.

10372{
10373 return !unarmed_attack();
10374}
bool unarmed_attack() const
True if unarmed or wielding a weapon with the UNARMED_WEAPON flag.
Definition: melee.cpp:210

References unarmed_attack().

Referenced by perform_technique(), pick_technique(), and npc::talk_to_u().

◆ head_cloth_encumbrance()

int Character::head_cloth_encumbrance ( ) const

Returns the total encumbrance of all SKINTIGHT and HELMET_COMPAT items coveringi the head.

Definition at line 8912 of file character.cpp.

8913{
8914 int ret = 0;
8915 for( auto &i : worn ) {
8916 const item *worn_item = &i;
8917 if( i.covers( bp_head ) && !i.has_flag( flag_SEMITANGIBLE ) &&
8918 ( worn_item->has_flag( flag_HELMET_COMPAT ) || worn_item->has_flag( flag_SKINTIGHT ) ) ) {
8919 ret += worn_item->get_encumber( *this );
8920 }
8921 }
8922 return ret;
8923}

References bp_head, flag_HELMET_COMPAT(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), item::get_encumber(), item::has_flag(), cata::hash64_detail::ret, and worn.

Referenced by can_wear().

◆ heal()

void Character::heal ( const bodypart_id healed,
int  dam 
)

Heals a body_part for dam.

Definition at line 8646 of file character.cpp.

8647{
8648 if( !is_limb_broken( healed ) ) {
8649 int effective_heal = std::min( dam, get_part_hp_max( healed ) - get_part_hp_cur( healed ) );
8650 mod_part_hp_cur( healed, effective_heal );
8651 g->events().send<event_type::character_heals_damage>( getID(), effective_heal );
8652 }
8653}
@ character_heals_damage

References character_heals_damage, g, Creature::get_part_hp_cur(), Creature::get_part_hp_max(), getID(), is_limb_broken(), and Creature::mod_part_hp_cur().

Referenced by enforce_minimum_healing(), heal_actor::finish_using(), give_aid_to(), healall(), process_bionic(), regen(), and suffer_water_damage().

◆ healall()

void Character::healall ( int  dam)

Heals all body parts for dam.

Definition at line 8655 of file character.cpp.

8656{
8657 for( const bodypart_id &bp : get_all_body_parts() ) {
8658 heal( bp, dam );
8659 mod_part_healed_total( bp, dam );
8660 }
8661}
void mod_part_healed_total(const bodypart_id &id, int mod)
Definition: creature.cpp:1646

References Creature::get_all_body_parts(), heal(), and Creature::mod_part_healed_total().

Referenced by iuse::artifact(), consume_effects(), hardcoded_effects(), spell::heal(), iuse::jet_injector(), melee_attack(), iuse::mycus(), regen(), and suffer_from_radiation().

◆ healed_bp()

void Character::healed_bp ( int  bp,
int  amount 
)

Definition at line 7744 of file character.cpp.

7745{
7746 healed_total[bp] += amount;
7747}

References healed_total.

Referenced by regen().

◆ healing_rate()

float Character::healing_rate ( float  at_rest_quality) const

Average hit points healed per turn.

Definition at line 6656 of file character.cpp.

6657{
6658 // TODO: Cache
6659 float heal_rate;
6660 if( !is_npc() ) {
6661 heal_rate = get_option< float >( "PLAYER_HEALING_RATE" );
6662 } else {
6663 heal_rate = get_option< float >( "NPC_HEALING_RATE" );
6664 }
6665 float awake_rate = heal_rate * mutation_value( "healing_awake" );
6666 float final_rate = 0.0f;
6667 if( awake_rate > 0.0f ) {
6668 final_rate += awake_rate;
6669 } else if( at_rest_quality < 1.0f ) {
6670 // Resting protects from rot
6671 final_rate += ( 1.0f - at_rest_quality ) * awake_rate;
6672 }
6673 float asleep_rate = 0.0f;
6674 if( at_rest_quality > 0.0f ) {
6675 asleep_rate = at_rest_quality * heal_rate * ( 1.0f + mutation_value( "healing_resting" ) );
6676 }
6677 if( asleep_rate > 0.0f ) {
6678 final_rate += asleep_rate * ( 1.0f + get_healthy() / 200.0f );
6679 }
6680
6681 // Most common case: awake player with no regenerative abilities
6682 // ~7e-5 is 1 hp per day, anything less than that is totally negligible
6683 static constexpr float eps = 0.000007f;
6684 add_msg( m_debug, "%s healing: %.6f", name, final_rate );
6685 if( std::abs( final_rate ) < eps ) {
6686 return 0.0f;
6687 }
6688
6689 float primary_hp_mod = mutation_value( "hp_modifier" );
6690 if( primary_hp_mod < 0.0f ) {
6691 // HP mod can't get below -1.0
6692 final_rate *= 1.0f + primary_hp_mod;
6693 }
6694
6695 return final_rate;
6696}

References add_msg(), get_healthy(), Creature::is_npc(), m_debug, mutation_value(), and name.

Referenced by regen().

◆ healing_rate_medicine()

float Character::healing_rate_medicine ( float  at_rest_quality,
const bodypart_id bp 
) const

Average hit points healed per turn from healing effects.

Definition at line 6698 of file character.cpp.

6699{
6700 float rate_medicine = 0.0f;
6701 float bandaged_rate = 0.0f;
6702 float disinfected_rate = 0.0f;
6703
6704 const effect &e_bandaged = get_effect( effect_bandaged, bp->token );
6705 const effect &e_disinfected = get_effect( effect_disinfected, bp->token );
6706
6707 if( !e_bandaged.is_null() ) {
6708 bandaged_rate += static_cast<float>( e_bandaged.get_amount( "HEAL_RATE" ) ) / to_turns<int>
6709 ( 24_hours );
6710 if( bp == bodypart_id( "head" ) ) {
6711 bandaged_rate *= e_bandaged.get_amount( "HEAL_HEAD" ) / 100.0f;
6712 }
6713 if( bp == bodypart_id( "torso" ) ) {
6714 bandaged_rate *= e_bandaged.get_amount( "HEAL_TORSO" ) / 100.0f;
6715 }
6716 }
6717
6718 if( !e_disinfected.is_null() ) {
6719 disinfected_rate += static_cast<float>( e_disinfected.get_amount( "HEAL_RATE" ) ) / to_turns<int>
6720 ( 24_hours );
6721 if( bp == bodypart_id( "head" ) ) {
6722 disinfected_rate *= e_disinfected.get_amount( "HEAL_HEAD" ) / 100.0f;
6723 }
6724 if( bp == bodypart_id( "torso" ) ) {
6725 disinfected_rate *= e_disinfected.get_amount( "HEAL_TORSO" ) / 100.0f;
6726 }
6727 }
6728
6729 rate_medicine += bandaged_rate + disinfected_rate;
6730 rate_medicine *= 1.0f + mutation_value( "healing_resting" );
6731 rate_medicine *= 1.0f + at_rest_quality;
6732
6733 // increase healing if character has both effects
6734 if( !e_bandaged.is_null() && !e_disinfected.is_null() ) {
6735 rate_medicine *= 2;
6736 }
6737
6738 if( get_healthy() > 0.0f ) {
6739 rate_medicine *= 1.0f + get_healthy() / 200.0f;
6740 } else {
6741 rate_medicine *= 1.0f + get_healthy() / 400.0f;
6742 }
6743 float primary_hp_mod = mutation_value( "hp_modifier" );
6744 if( primary_hp_mod < 0.0f ) {
6745 // HP mod can't get below -1.0
6746 rate_medicine *= 1.0f + primary_hp_mod;
6747 }
6748 return rate_medicine;
6749}
int get_amount(std::string arg, bool reduced=false) const
Returns the amount of a modifier type applied when a new effect is first added.
Definition: effect.cpp:974

References effect_bandaged, effect_disinfected, effect::get_amount(), Creature::get_effect(), get_healthy(), effect::is_null(), and mutation_value().

Referenced by regen().

◆ hearing_ability()

float Character::hearing_ability ( ) const

Definition at line 10296 of file character.cpp.

10297{
10298 float volume_multiplier = 1.0;
10299
10300 // Mutation/Bionic volume modifiers
10302 volume_multiplier *= 3.5;
10303 }
10304 if( has_trait( trait_PER_SLIME ) ) {
10305 // Random hearing :-/
10306 // (when it's working at all, see player.cpp)
10307 // changed from 0.5 to fix Mac compiling error
10308 volume_multiplier *= ( rng( 1, 2 ) );
10309 }
10310
10311 volume_multiplier *= Character::mutation_value( "hearing_modifier" );
10312
10313 if( has_effect( effect_deaf ) ) {
10314 // Scale linearly up to 30 minutes
10315 volume_multiplier *= ( 30_minutes - get_effect_dur( effect_deaf ) ) / 30_minutes;
10316 }
10317
10318 if( has_effect( effect_earphones ) ) {
10319 volume_multiplier *= .25;
10320 }
10321
10322 return volume_multiplier;
10323}
static const trait_id trait_PER_SLIME("PER_SLIME")
static const efftype_id effect_deaf("deaf")
static const bionic_id bio_ears("bio_ears")
static const bionic_id bio_earplugs("bio_earplugs")
static const efftype_id effect_earphones("earphones")

References bio_earplugs, bio_ears, effect_deaf, effect_earphones, Creature::get_effect_dur(), has_active_bionic(), Creature::has_effect(), has_trait(), mutation_value(), rng(), and trait_PER_SLIME.

Referenced by can_hear(), and sounds::process_sound_markers().

◆ heat_emission()

void Character::heat_emission ( bionic bio,
int  fuel_energy 
)

Handle heat from exothermic power generation.

Definition at line 1497 of file bionics.cpp.

1498{
1499 if( !bio.info().exothermic_power_gen ) {
1500 return;
1501 }
1502 const float efficiency = bio.info().fuel_efficiency;
1503
1504 const int heat_prod = fuel_energy * ( 1.0f - efficiency );
1505 const int heat_level = std::min( heat_prod / 10, 4 );
1506 const emit_id hotness = emit_id( "emit_hot_air" + std::to_string( heat_level ) + "_cbm" );
1507 map &here = get_map();
1508 if( hotness.is_valid() ) {
1509 const int heat_spread = std::max( heat_prod / 10 - heat_level, 1 );
1510 here.emit_field( pos(), hotness, heat_spread );
1511 }
1512 for( const std::pair<const bodypart_str_id, int> &bp : bio.info().occupied_bodyparts ) {
1513 add_effect( effect_heating_bionic, 2_seconds, bp.first->token, heat_prod );
1514 }
1515}
static const efftype_id effect_heating_bionic("heating_bionic")
bool exothermic_power_gen
If true this bionic emits heat when producing power.
Definition: bionics.h:79
string_id< emit > emit_id
Definition: type_id.h:51

References Creature::add_effect(), effect_heating_bionic, map::emit_field(), bionic_data::exothermic_power_gen, bionic_data::fuel_efficiency, get_map(), bionic::info(), string_id< T >::is_valid(), bionic_data::occupied_bodyparts, pos(), and to_string().

Referenced by burn_fuel(), and passive_power_gen().

◆ height()

int Character::height ( ) const

Definition at line 6837 of file character.cpp.

6838{
6839 switch( get_size() ) {
6840 case MS_TINY:
6841 return init_height - 100;
6842 case MS_SMALL:
6843 return init_height - 50;
6844 case MS_MEDIUM:
6845 return init_height;
6846 case MS_LARGE:
6847 return init_height + 50;
6848 case MS_HUGE:
6849 return init_height + 100;
6850 default:
6851 break;
6852 }
6853
6854 debugmsg( "Invalid size class" );
6855 abort();
6856}
@ MS_TINY
Definition: creature.h:58
@ MS_LARGE
Definition: creature.h:61
@ MS_SMALL
Definition: creature.h:59
@ MS_HUGE
Definition: creature.h:62
@ MS_MEDIUM
Definition: creature.h:60

References abort, debugmsg, get_size(), init_height, MS_HUGE, MS_LARGE, MS_MEDIUM, MS_SMALL, and MS_TINY.

Referenced by bodyweight(), height_string(), and set_base_height().

◆ height_string()

std::string Character::height_string ( ) const

Definition at line 6822 of file character.cpp.

6823{
6824 const bool metric = get_option<std::string>( "DISTANCE_UNITS" ) == "metric";
6825
6826 if( metric ) {
6827 std::string metric_string = _( "%d cm" );
6828 return string_format( metric_string, height() );
6829 }
6830
6831 int total_inches = std::round( height() / 2.54 );
6832 int feet = std::floor( total_inches / 12 );
6833 int remainder_inches = total_inches % 12;
6834 return string_format( "%d\'%d\"", feet, remainder_inches );
6835}

References _, height(), and string_format().

Referenced by draw_stats_info(), and draw_stats_tab().

◆ hit_roll()

float Character::hit_roll ( ) const
overridevirtual

Returns the player's basic hit roll that is compared to the target's dodge roll.

Implements Creature.

Definition at line 357 of file melee.cpp.

358{
359 // Dexterity, skills, weapon and martial arts
360 float hit = get_melee_hit_base();
361
362 // Farsightedness makes us hit worse
363 if( has_trait( trait_HYPEROPIC ) && !worn_with_flag( "FIX_FARSIGHT" ) &&
365 hit -= 2.0f;
366 }
367
368 //Unstable ground chance of failure
370 hit *= 0.75f;
371 }
372
373 hit *= std::max( 0.25f, 1.0f - encumb( bp_torso ) / 100.0f );
374
375 return melee::melee_hit_range( hit );
376}
float get_melee_hit_base() const
Returns weapon skill.
Definition: melee.cpp:351
float melee_hit_range(float accuracy)
Once the accuracy (sum of modifiers) of an attack has been determined, this is used to actually roll ...
Definition: melee.cpp:2503

References bp_torso, effect_bouldering, effect_contacts, encumb(), get_melee_hit_base(), Creature::has_effect(), has_trait(), melee::melee_hit_range(), trait_HYPEROPIC, and worn_with_flag().

Referenced by melee_attack(), perform_special_attacks(), scored_crit(), and avatar_funcs::try_disarm_npc().

◆ hitall()

int Character::hitall ( int  dam,
int  vary,
Creature source 
)

Harms all body parts for dam, with armor reduction.

If vary > 0 damage to parts are random within vary % (1-100)

Definition at line 8681 of file character.cpp.

8682{
8683 int damage_taken = 0;
8684 for( int i = 0; i < num_hp_parts; i++ ) {
8685 const bodypart_id bp = convert_bp( hp_to_bp( static_cast<hp_part>( i ) ) ).id();
8686 int ddam = vary ? dam * rng( 100 - vary, 100 ) / 100 : dam;
8687 int cut = 0;
8688 auto damage = damage_instance::physical( ddam, cut, 0 );
8689 damage_taken += deal_damage( source, bp, damage ).total_damage();
8690 }
8691 return damage_taken;
8692}
static body_part hp_to_bp(hp_part hpart)
Converts an hp_part to a body_part.
Definition: character.cpp:6480
int_id< T > id() const
Translate the string based it to the matching integer based id.
Definition: ammo_effect.cpp:54

References convert_bp(), deal_damage(), hp_to_bp(), string_id< T >::id(), num_hp_parts, damage_instance::physical(), rng(), and dealt_damage_instance::total_damage().

Referenced by game::forced_door_closing(), and vehicle::part_collision().

◆ hp_percentage()

int Character::hp_percentage ( ) const
overridevirtual

Returns overall % of HP remaining.

Implements Creature.

Definition at line 11042 of file character.cpp.

11043{
11044 const bodypart_id head_id = bodypart_id( "head" );
11045 const bodypart_id torso_id = bodypart_id( "torso" );
11046 int total_cur = 0;
11047 int total_max = 0;
11048 // Head and torso HP are weighted 3x and 2x, respectively
11049 total_cur = get_part_hp_cur( head_id ) * 3 + get_part_hp_cur( torso_id ) * 2;
11050 total_max = get_part_hp_max( head_id ) * 3 + get_part_hp_max( torso_id ) * 2;
11051 for( const std::pair< const bodypart_str_id, bodypart> &elem : get_body() ) {
11052 total_cur += elem.second.get_hp_cur();
11053 total_max += elem.second.get_hp_max();
11054 }
11055
11056 return ( 100 * total_cur ) / total_max;
11057}

References Creature::get_body(), Creature::get_part_hp_cur(), and Creature::get_part_hp_max().

Referenced by npc::character_danger(), npc::emergency(), npc::hp_description(), and npc::process_turn().

◆ hp_to_bp()

body_part Character::hp_to_bp ( hp_part  hpart)
static

Converts an hp_part to a body_part.

Definition at line 6480 of file character.cpp.

6481{
6482 switch( hpart ) {
6483 case hp_head:
6484 return bp_head;
6485 case hp_torso:
6486 return bp_torso;
6487 case hp_arm_l:
6488 return bp_arm_l;
6489 case hp_arm_r:
6490 return bp_arm_r;
6491 case hp_leg_l:
6492 return bp_leg_l;
6493 case hp_leg_r:
6494 return bp_leg_r;
6495 default:
6496 return num_bp;
6497 }
6498}

References bp_arm_l, bp_arm_r, bp_head, bp_leg_l, bp_leg_r, bp_torso, hp_arm_l, hp_arm_r, hp_head, hp_leg_l, hp_leg_r, hp_torso, and num_bp.

Referenced by iexamine::autodoc(), cauterize_actor::cauterize_effect(), draw_limb_health(), heal_actor::finish_using(), hitall(), impact(), pick_part_to_heal(), map::player_in_field(), regen(), heal_actor::use_healing_item(), and npc::wear_if_wanted().

◆ hurtall()

void Character::hurtall ( int  dam,
Creature source,
bool  disturb = true 
)

Hurts all body parts for dam, no armor reduction.

Definition at line 8663 of file character.cpp.

8664{
8665 if( is_dead_state() || has_trait( trait_DEBUG_NODMG ) || dam <= 0 ) {
8666 return;
8667 }
8668
8669 for( const bodypart_id &bp : get_all_body_parts( true ) ) {
8670 // Don't use apply_damage here or it will annoy the player with 6 queries
8671 const int dam_to_bodypart = std::min( dam, get_part_hp_cur( bp ) );
8672 mod_part_hp_cur( bp, - dam_to_bodypart );
8673 g->events().send<event_type::character_takes_damage>( getID(), dam_to_bodypart );
8674 }
8675
8676 // Low pain: damage is spread all over the body, so not as painful as 6 hits in one part
8677 mod_pain( dam );
8678 on_hurt( source, disturb );
8679}

References character_takes_damage, g, Creature::get_all_body_parts(), Creature::get_part_hp_cur(), getID(), has_trait(), is_dead_state(), mod_pain(), Creature::mod_part_hp_cur(), on_hurt(), and trait_DEBUG_NODMG.

Referenced by trapfunc::drain(), hardcoded_effects(), marloss_common(), trapfunc::pit(), map::player_in_field(), game::process_artifact(), relic_funcs::process_recharge_entry(), regen(), map::shake_vehicle(), suffer_from_bad_bionics(), suffer_from_radiation(), trapfunc::tripwire(), and try_reject_mutagen().

◆ i_add()

item & Character::i_add ( item  it,
bool  should_stack = true 
)

Definition at line 2267 of file character.cpp.

2268{
2269 itype_id item_type_id = it.typeId();
2270 last_item = item_type_id;
2271
2272 if( it.is_food() || it.is_ammo() || it.is_gun() || it.is_armor() ||
2273 it.is_book() || it.is_tool() || it.is_melee() || it.is_food_container() ) {
2274 inv.unsort();
2275 }
2276
2277 // if there's a desired invlet for this item type, try to use it
2278 bool keep_invlet = false;
2279 const invlets_bitset cur_inv = allocated_invlets();
2280 for( auto iter : inv.assigned_invlet ) {
2281 if( iter.second == item_type_id && !cur_inv[iter.first] ) {
2282 it.invlet = iter.first;
2283 keep_invlet = true;
2284 break;
2285 }
2286 }
2287 auto &item_in_inv = inv.add_item( it, keep_invlet, true, should_stack );
2288 item_in_inv.on_pickup( *this );
2291 return item_in_inv;
2292}
@ reloadables
Definition: character.h:102
@ reloadable_cbms
Definition: character.h:103
itype_id last_item
Definition: character.h:1582
std::bitset< std::numeric_limits< char >::max()> allocated_invlets() const
Only use for UI things.
Definition: character.cpp:2494
std::map< char, itype_id > assigned_invlet
Definition: inventory.h:99
bool is_gun() const
Can this item be used to perform a ranged attack?
Definition: item.cpp:6542
bool is_food_container() const
Definition: item.cpp:6633
bool is_book() const
Definition: item.cpp:6734
bool is_ammo() const
Definition: item.cpp:6607
void on_pickup(Character &p)
Callback when a player starts carrying the item.
Definition: item.cpp:4536
bool is_melee(damage_type dt) const
Is this item an effective melee weapon for the given damage type?
Definition: item.cpp:6702

References inventory::add_item(), allocated_invlets(), inventory::assigned_invlet, clear_npc_ai_info_cache(), inv, item::invlet, item::is_ammo(), item::is_armor(), item::is_book(), item::is_food(), item::is_food_container(), item::is_gun(), item::is_melee(), item::is_tool(), last_item, item::on_pickup(), reloadable_cbms, reloadables, item::typeId(), and inventory::unsort().

Referenced by avatar_funcs::add_or_drop_with_msg(), iuse::adrenaline_injector(), iuse::arrow_flammable(), monexamine::attach_or_remove_saddle(), debug_menu::debug(), fetch_activity(), give_item_to(), handle_harvest(), i_add_or_drop(), mount_creature(), npc::mug_player(), iuse::multicooker(), item_location::impl::item_on_map::obtain(), item_location::impl::item_on_person::obtain(), item_location::impl::item_on_vehicle::obtain(), item_location::impl::item_in_container::obtain(), pick_one_up(), npc::pick_up_item(), iuse::purify_smart(), iuse::radiocar(), item::reload(), monexamine::remove_leash(), mattack::riotbot(), talk_effect_fun_t::set_bulk_trade_accept(), set_item_inventory(), talk_effect_fun_t::set_u_buy_item(), talk_effect_fun_t::set_u_sell_item(), gun_actor::shoot(), spell_effect::spawn_ethereal_item(), npc::stow_item(), monexamine::take_items_from(), npc_trading::transfer_items(), avatar_funcs::try_steal_from_npc(), ammobelt_actor::use(), iuse::vaccine(), and avatar_action::wield().

◆ i_add_or_drop()

bool Character::i_add_or_drop ( item it,
int  qty = 1 
)

Sets invlet and adds to inventory if possible, drops otherwise, returns true if either succeeded.

An optional qty can be provided (and will perform better than separate calls).

Definition at line 2407 of file character.cpp.

2408{
2409 bool retval = true;
2410 bool drop = it.made_of( LIQUID );
2411 inv.assign_empty_invlet( it, *this );
2412 map &here = get_map();
2413 for( int i = 0; i < qty; ++i ) {
2414 drop |= !can_pick_weight( it, !get_option<bool>( "DANGEROUS_PICKUPS" ) ) || !can_pick_volume( it );
2415 if( drop ) {
2416 retval &= !here.add_item_or_charges( pos(), it ).is_null();
2417 } else {
2418 i_add( it );
2419 }
2420 }
2421
2422 return retval;
2423}
item & i_add(item it, bool should_stack=true)
Definition: character.cpp:2267
bool can_pick_volume(const item &it) const
Definition: character.cpp:2706
void assign_empty_invlet(item &it, const Character &p, bool force=false)
Definition: inventory.cpp:1151

References map::add_item_or_charges(), inventory::assign_empty_invlet(), can_pick_volume(), can_pick_weight(), drop(), get_map(), i_add(), inv, item::is_null(), LIQUID, item::made_of(), and pos().

Referenced by activate_mutation(), salvage_actor::cut_up(), drop_or_handle(), heal_actor::finish_using(), avatar_funcs::gunmod_remove(), item_contents::handle_liquid_or_spill(), iexamine::pedestal_wyrm(), item::reload(), remove_radio_mod(), avatar_funcs::unload_item(), consume_drug_iuse::use(), bandolier_actor::use(), iexamine::vending(), and debug_menu::wishitem().

◆ i_add_to_container()

int Character::i_add_to_container ( const item it,
bool  unloading 
)

Try to find a container/s on character containing ammo of type it.typeId() and add charges until the container is full.

Parameters
unloadingDo not try to add to a container when the item was intentionally unloaded.
Returns
Remaining charges which could not be stored in a container.

Definition at line 2231 of file character.cpp.

2232{
2233 int charges = it.charges;
2234 if( !it.is_ammo() || unloading ) {
2235 return charges;
2236 }
2237
2238 const itype_id item_type = it.typeId();
2239 auto add_to_container = [&it, &charges]( item & container ) {
2240 auto &contained_ammo = container.contents.front();
2241 if( contained_ammo.charges < container.ammo_capacity() ) {
2242 const int diff = container.ammo_capacity() - contained_ammo.charges;
2243 //~ %1$s: item name, %2$s: container name
2244 add_msg( pgettext( "container", "You put the %1$s in your %2$s." ), it.tname(), container.tname() );
2245 if( diff > charges ) {
2246 contained_ammo.charges += charges;
2247 return 0;
2248 } else {
2249 contained_ammo.charges = container.ammo_capacity();
2250 return charges - diff;
2251 }
2252 }
2253 return charges;
2254 };
2255
2256 visit_items( [ & ]( item * item ) {
2257 if( charges > 0 && item->is_ammo_container() && item_type == item->contents.front().typeId() ) {
2258 charges = add_to_container( *item );
2259 item->handle_pickup_ownership( *this );
2260 }
2261 return VisitResponse::NEXT;
2262 } );
2263
2264 return charges;
2265}
bool is_ammo_container() const
Definition: item.cpp:6687
VisitResponse visit_items(const std::function< VisitResponse(item *, item *)> &func)
Traverses this object and any child items contained using a visitor pattern.
Definition: visitable.cpp:422

References add_msg(), item::charges, item::contents, item_contents::front(), item::is_ammo(), item::is_ammo_container(), NEXT, pgettext(), item::tname(), item::typeId(), and visitable< Character >::visit_items().

Referenced by avatar_funcs::add_or_drop_with_msg(), and pick_one_up().

◆ i_at() [1/2]

◆ i_at() [2/2]

const item & Character::i_at ( int  position) const

Definition at line 2332 of file character.cpp.

2333{
2334 if( position == -1 ) {
2335 return primary_weapon();
2336 }
2337 if( position < -1 ) {
2338 int worn_index = worn_position_to_index( position );
2339 if( static_cast<size_t>( worn_index ) < worn.size() ) {
2340 auto iter = worn.begin();
2341 std::advance( iter, worn_index );
2342 return *iter;
2343 }
2344 }
2345
2346 return inv.find_item( position );
2347}
const item & find_item(int position) const
Definition: inventory.cpp:800

References inventory::find_item(), inv, position, primary_weapon(), worn, and worn_position_to_index().

◆ i_rem() [1/2]

item Character::i_rem ( const item it)

Remove a specific item from player possession.

The item is compared by pointer. Contents of the item are removed as well.

Parameters
itA pointer to the item to be removed. The item must exists in the players possession (one can use has_item to check for this).
Returns
A copy of the removed item.

Definition at line 2390 of file character.cpp.

2391{
2392 auto tmp = remove_items_with( [&it]( const item & i ) {
2393 return &i == it;
2394 }, 1 );
2395 if( tmp.empty() ) {
2396 debugmsg( "did not found item %s to remove it!", it->tname() );
2397 return item();
2398 }
2399 return tmp.front();
2400}
std::list< item > remove_items_with(const std::function< bool(const item &)> &filter, int count=INT_MAX)
Removes items contained by this instance which match the filter.

References debugmsg, visitable< Character >::remove_items_with(), and item::tname().

◆ i_rem() [2/2]

item Character::i_rem ( int  pos)

Remove a specific item from player possession.

The item is compared by pointer. Contents of the item are removed as well.

Parameters
posThe item position of the item to be removed. The item must exists, use has_item to check this.
Returns
A copy of the removed item.

Definition at line 2372 of file character.cpp.

2373{
2374 item tmp;
2375 if( pos == -1 ) {
2376 tmp = primary_weapon();
2378 return tmp;
2379 } else if( pos < -1 && pos > worn_position_to_index( worn.size() ) ) {
2380 auto iter = worn.begin();
2381 std::advance( iter, worn_position_to_index( pos ) );
2382 tmp = *iter;
2383 tmp.on_takeoff( *this );
2384 worn.erase( iter );
2385 return tmp;
2386 }
2387 return inv.remove_item( pos );
2388}

References inv, item::on_takeoff(), pos(), primary_weapon(), inventory::remove_item(), set_primary_weapon(), worn, and worn_position_to_index().

Referenced by monexamine::add_leash(), apply_damage(), monexamine::attach_bag_to(), mattack::bio_op_disarm(), iuse::blood_draw(), consume(), consume_charges(), drop_invalid_inventory(), npc::drop_items(), iuse::fish_trap(), give_item_to(), activity_handlers::gunmod_add_finish(), ranged::handle_gun_damage(), i_rem_keep_contents(), monexamine::insert_battery(), invoke_item(), activity_handlers::lockpicking_finish(), iuse::lumber(), npc::mug_player(), npc_throw(), pickup::obtain_and_tokenize_items(), iuse::radiocar(), player::reduce_charges(), character_funcs::store_in_container(), tidy_activity(), avatar_funcs::try_disarm_npc(), avatar_funcs::try_steal_from_npc(), unpack_actor::use(), and avatar::wield().

◆ i_rem_keep_contents()

void Character::i_rem_keep_contents ( int  idx)

Definition at line 2402 of file character.cpp.

2403{
2404 i_rem( idx ).spill_contents( pos() );
2405}

References i_rem(), pos(), and item::spill_contents().

Referenced by damage_item(), and sew_advanced_actor::use().

◆ impact()

int Character::impact ( int  force,
const tripoint pos 
)
overridevirtual

Deals falling/collision damage with terrain/creature at pos.

Implements Creature.

Definition at line 10830 of file character.cpp.

10831{
10832 // Falls over ~30m are fatal more often than not
10833 // But that would be quite a lot considering 21 z-levels in game
10834 // so let's assume 1 z-level is comparable to 30 force
10835
10836 if( force <= 0 ) {
10837 return force;
10838 }
10839
10840 // Damage modifier (post armor)
10841 float mod = 1.0f;
10842 int effective_force = force;
10843 int cut = 0;
10844 // Percentage armor penetration - armor won't help much here
10845 // TODO: Make cushioned items like bike helmets help more
10846 float armor_eff = 1.0f;
10847 // Shock Absorber CBM heavily reduces damage
10848 const bool shock_absorbers = has_active_bionic( bionic_id( "bio_shock_absorber" ) );
10849
10850 // Being slammed against things rather than landing means we can't
10851 // control the impact as well
10852 const bool slam = p != pos();
10853 std::string target_name = "a swarm of bugs";
10854 Creature *critter = g->critter_at( p );
10855 if( critter != this && critter != nullptr ) {
10856 target_name = critter->disp_name();
10857 // Slamming into creatures and NPCs
10858 // TODO: Handle spikes/horns and hard materials
10859 armor_eff = 0.5f; // 2x as much as with the ground
10860 // TODO: Modify based on something?
10861 mod = 1.0f;
10862 effective_force = force;
10863 } else if( const optional_vpart_position vp = g->m.veh_at( p ) ) {
10864 // Slamming into vehicles
10865 // TODO: Integrate it with vehicle collision function somehow
10866 target_name = vp->vehicle().disp_name();
10867 if( vp.part_with_feature( "SHARP", true ) ) {
10868 // Now we're actually getting impaled
10869 cut = force; // Lots of fun
10870 }
10871
10872 mod = slam ? 1.0f : fall_damage_mod();
10873 armor_eff = 0.25f; // Not much
10874 if( !slam && vp->part_with_feature( "ROOF", true ) ) {
10875 // Roof offers better landing than frame or pavement
10876 // TODO: Make this not happen with heavy duty/plated roof
10877 effective_force /= 2;
10878 }
10879 } else {
10880 // Slamming into terrain/furniture
10881 target_name = g->m.disp_name( p );
10882 int hard_ground = g->m.has_flag( TFLAG_DIGGABLE, p ) ? 0 : 3;
10883 armor_eff = 0.25f; // Not much
10884 // Get cut by stuff
10885 // This isn't impalement on metal wreckage, more like flying through a closed window
10886 cut = g->m.has_flag( TFLAG_SHARP, p ) ? 5 : 0;
10887 effective_force = force + hard_ground;
10888 mod = slam ? 1.0f : fall_damage_mod();
10889 if( g->m.has_furn( p ) ) {
10890 // TODO: Make furniture matter
10891 } else if( g->m.has_flag( TFLAG_SWIMMABLE, p ) ) {
10892 // TODO: Some formula of swimming
10893 effective_force /= 4;
10894 }
10895 }
10896
10897 // Rescale for huge force
10898 // At >30 force, proper landing is impossible and armor helps way less
10899 if( effective_force > 30 ) {
10900 // Armor simply helps way less
10901 armor_eff *= 30.0f / effective_force;
10902 if( mod < 1.0f ) {
10903 // Everything past 30 damage gets a worse modifier
10904 const float scaled_mod = std::pow( mod, 30.0f / effective_force );
10905 const float scaled_damage = ( 30.0f * mod ) + scaled_mod * ( effective_force - 30.0f );
10906 mod = scaled_damage / effective_force;
10907 }
10908 }
10909
10910 if( !slam && mod < 1.0f && mod * force < 5 ) {
10911 // Perfect landing, no damage (regardless of armor)
10912 add_msg_if_player( m_warning, _( "You land on %s." ), target_name );
10913 return 0;
10914 }
10915
10916 // Shock absorbers kick in only when they need to, so if our other protections fail, fall back on them
10917 if( shock_absorbers ) {
10918 effective_force -= 15; // Provide a flat reduction to force
10919 if( mod > 0.25f ) {
10920 mod = 0.25f; // And provide a 75% reduction against that force if we don't have it already
10921 }
10922 if( effective_force < 0 ) {
10923 effective_force = 0;
10924 }
10925 }
10926
10927 int total_dealt = 0;
10928 if( mod * effective_force >= 5 ) {
10929 for( int i = 0; i < num_hp_parts; i++ ) {
10930 const bodypart_id bp = convert_bp( hp_to_bp( static_cast<hp_part>( i ) ) ).id();
10931 const int bash = effective_force * rng( 60, 100 ) / 100;
10932 damage_instance di;
10933 di.add_damage( DT_BASH, bash, 0, armor_eff, mod );
10934 // No good way to land on sharp stuff, so here modifier == 1.0f
10935 di.add_damage( DT_CUT, cut, 0, armor_eff, 1.0f );
10936 total_dealt += deal_damage( nullptr, bp, di ).total_damage();
10937 }
10938 }
10939
10940 if( total_dealt > 0 && is_player() ) {
10941 // "You slam against the dirt" is fine
10942 add_msg( m_bad, _( "You are slammed against %1$s for %2$d damage." ),
10943 target_name, total_dealt );
10944 } else if( is_player() && shock_absorbers ) {
10945 add_msg( m_bad, _( "You are slammed against %s!" ),
10946 target_name, total_dealt );
10947 add_msg( m_good, _( "…but your shock absorbers negate the damage!" ) );
10948 } else if( slam ) {
10949 // Only print this line if it is a slam and not a landing
10950 // Non-players should only get this one: player doesn't know how much damage was dealt
10951 // and landing messages for each slammed creature would be too much
10953 _( "You are slammed against %s." ),
10954 _( "<npcname> is slammed against %s." ),
10955 target_name );
10956 } else {
10957 // No landing message for NPCs
10958 add_msg_if_player( m_warning, _( "You land on %s." ), target_name );
10959 }
10960
10961 if( x_in_y( mod, 1.0f ) ) {
10962 add_effect( effect_downed, rng( 1_turns, 1_turns + mod * 3_turns ) );
10963 }
10964
10965 return total_dealt;
10966}
float fall_damage_mod() const override
Returns multiplier on fall damage at low velocity (knockback/pit/1 z-level, not 5 z-levels)
@ TFLAG_DIGGABLE
Definition: mapdata.h:297
@ TFLAG_SWIMMABLE
Definition: mapdata.h:279
@ TFLAG_SHARP
Definition: mapdata.h:296
void bash(const spell &sp, Creature &caster, const tripoint &target)

References _, damage_instance::add_damage(), Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), spell_effect::bash(), bionic_id, convert_bp(), deal_damage(), Creature::disp_name(), DT_BASH, DT_CUT, effect_downed, fall_damage_mod(), g, has_active_bionic(), hp_to_bp(), string_id< T >::id(), Creature::is_player(), m_bad, m_good, m_warning, num_hp_parts, pos(), rng(), TFLAG_DIGGABLE, TFLAG_SHARP, TFLAG_SWIMMABLE, dealt_damage_instance::total_damage(), and x_in_y().

Referenced by trapfunc::ledge().

◆ in_climate_control()

bool Character::in_climate_control ( )

Returns true if the player is in a climate controlled area or armor.

Definition at line 3852 of file character.cpp.

3853{
3854 bool regulated_area = false;
3855 // Check
3857 return true;
3858 }
3859 map &here = get_map();
3861 in_sleep_state() ) {
3862 return true;
3863 }
3864 for( auto &w : worn ) {
3865 if( w.has_flag( flag_CLIMATE_CONTROL.str() ) ) {
3866 return true;
3867 }
3868 }
3870 // save CPU and simulate acclimation.
3872 if( const optional_vpart_position vp = here.veh_at( pos() ) ) {
3873 // TODO: (?) Force player to scrounge together an AC unit
3874 regulated_area = (
3875 vp->is_inside() && // Already checks for opened doors
3876 vp->vehicle().total_power_w( true ) > 0 // Out of gas? No AC for you!
3877 );
3878 }
3879 // TODO: AC check for when building power is implemented
3880 last_climate_control_ret = regulated_area;
3881 if( !regulated_area ) {
3882 // Takes longer to cool down / warm up with AC, than it does to step outside and feel cruddy.
3883 next_climate_control_check += 40_turns;
3884 }
3885 } else {
3887 }
3888 return regulated_area;
3889}
static const trait_id trait_M_SKIN3("M_SKIN3")
static const flag_str_id flag_CLIMATE_CONTROL("CLIMATE_CONTROL")
static const bionic_id bio_climate("bio_climate")
static const std::string flag_FUNGUS("FUNGUS")
bool has_flag_ter_or_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2403

References bio_climate, flag_CLIMATE_CONTROL, flag_FUNGUS(), get_map(), has_active_bionic(), map::has_flag_ter_or_furn(), has_trait(), in_sleep_state(), last_climate_control_ret, next_climate_control_check, pos(), string_id< T >::str(), trait_M_SKIN3, calendar::turn, map::veh_at(), and worn.

Referenced by update_bodytemp().

◆ in_sleep_state()

◆ in_species()

bool Character::in_species ( const species_id spec) const
overridevirtual

Reimplemented from Creature.

Definition at line 529 of file character.cpp.

530{
531 return spec == HUMAN;
532}
static const species_id HUMAN("HUMAN")

References HUMAN.

◆ initialize_stomach_contents()

void Character::initialize_stomach_contents ( )

Definition at line 195 of file stomach.cpp.

196{
198}

References stomach.

◆ install_bionics()

bool Character::install_bionics ( const itype type,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Initialize all the values needed to start the operation player_activity.

Definition at line 2322 of file bionics.cpp.

2324{
2325 if( !type.bionic ) {
2326 debugmsg( "Tried to install NULL bionic" );
2327 return false;
2328 }
2329
2330 const bionic_id &bioid = type.bionic->id;
2331 const bionic_id &upbioid = bioid->upgraded_bionic;
2332 const int difficulty = type.bionic->difficulty;
2333 float adjusted_skill;
2334 int pl_skill;
2335 if( autodoc ) {
2336 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
2339 skill_level );
2340 pl_skill = installer.bionics_pl_skill( skill_firstaid,
2343 skill_level );
2344 } else {
2345 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
2348 skill_level );
2349 pl_skill = installer.bionics_pl_skill( skill_electronics,
2352 skill_level );
2353 }
2354 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty );
2355
2356 // Practice skills only if conducting manual installation
2357 if( !autodoc ) {
2358 installer.practice( skill_electronics, static_cast<int>( ( 100 - chance_of_success ) * 1.5 ) );
2359 installer.practice( skill_firstaid, static_cast<int>( ( 100 - chance_of_success ) * 1.0 ) );
2360 installer.practice( skill_mechanics, static_cast<int>( ( 100 - chance_of_success ) * 0.5 ) );
2361 }
2362
2363 int success = chance_of_success - rng( 0, 99 );
2364 if( installer.has_trait( trait_DEBUG_BIONICS ) ) {
2365 perform_install( bioid, upbioid, difficulty, success, pl_skill, "NOT_MED",
2366 bioid->canceled_mutations );
2367 return true;
2368 }
2369 assign_activity( ACT_OPERATION, to_moves<int>( difficulty * 20_minutes ) );
2370 activity.values.push_back( difficulty );
2371 activity.values.push_back( success );
2372 activity.values.push_back( units::to_joule( bioid->capacity ) );
2373 activity.values.push_back( pl_skill );
2374 activity.str_values.push_back( "install" );
2375 activity.str_values.push_back( bioid.str() );
2376
2377 if( installer.has_trait( trait_PROF_MED ) || installer.has_trait( trait_PROF_AUTODOC ) ) {
2378 activity.str_values.push_back( installer.disp_name( true ) );
2379 } else {
2380 activity.str_values.push_back( "NOT_MED" );
2381 }
2382 if( autodoc ) {
2383 activity.str_values.push_back( "true" );
2384 } else {
2385 activity.str_values.push_back( "false" );
2386 }
2387 for( const std::pair<const bodypart_str_id, int> &elem : bioid->occupied_bodyparts ) {
2388 add_effect( effect_under_op, difficulty * 20_minutes, elem.first->token, difficulty );
2389 }
2390
2391 return true;
2392}
static const activity_id ACT_OPERATION("ACT_OPERATION")
void perform_install(bionic_id bid, bionic_id upbid, int difficulty, int success, int pl_skill, const std::string &installer_name, const std::vector< trait_id > &trait_to_rem)
Success or failure of installation happens here.
Definition: bionics.cpp:2394
void practice(const skill_id &id, int amount, int cap=99, bool suppress_warning=false)
This handles giving xp for a skill.
Definition: character.cpp:3415
std::vector< std::string > str_values
constexpr value_type to_joule(const quantity< value_type, energy_in_joule_tag > &v)
Definition: units_energy.h:40
bionic_id upgraded_bionic
Id of another bionic which this bionic can upgrade.
Definition: bionics.h:131

References ACT_OPERATION, activity, Creature::add_effect(), assign_activity(), iexamine::autodoc(), bionic_manip_cos(), bionics_adjusted_skill(), bionics_pl_skill(), bionic_data::canceled_mutations, bionic_data::capacity, debugmsg, disp_name(), effect_under_op, has_trait(), bionic_data::occupied_bodyparts, perform_install(), practice(), rng(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, string_id< T >::str(), player_activity::str_values, behavior::success, units::to_joule(), trait_DEBUG_BIONICS, trait_PROF_AUTODOC, trait_PROF_MED, type, bionic_data::upgraded_bionic, and player_activity::values.

Referenced by iexamine::autodoc(), and install_bionic_actor::use().

◆ introduce_into_anesthesia()

void Character::introduce_into_anesthesia ( const time_duration duration,
player installer,
bool  needs_anesthesia 
)

Handles process of introducing patient into anesthesia during Autodoc operations.

Requires anesthesia kits or NOPAIN mutation

Definition at line 2908 of file bionics.cpp.

2910{
2911 if( installer.has_trait( trait_DEBUG_BIONICS ) ) {
2912 installer.add_msg_if_player( m_info,
2913 _( "You tell the pain to bug off and proceed with the operation." ) );
2914 return;
2915 }
2916 installer.add_msg_player_or_npc( m_info,
2917 _( "You set up the operation step-by-step, configuring the Autodoc to manipulate a CBM." ),
2918 _( "<npcname> sets up the operation, configuring the Autodoc to manipulate a CBM." ) );
2919
2921 _( "You settle into position, sliding your right wrist into the couch's strap." ),
2922 _( "<npcname> settles into position, sliding their wrist into the couch's strap." ) );
2923 if( needs_anesthesia ) {
2924 //post-threshold medical mutants do not fear operations.
2927 _( "You feel excited as the operation starts." ) );
2928 }
2929
2931 _( "You feel a tiny pricking sensation in your right arm, and lose all sensation before abruptly blacking out." ) );
2932
2933 //post-threshold medical mutants with Deadened don't need anesthesia due to their inability to feel pain
2934 } else {
2935 //post-threshold medical mutants do not fear operations.
2938 _( "You feel excited as the Autodoc slices painlessly into you. You enjoy the sight of scalpels slicing you apart." ) );
2939 } else {
2941 _( "You stay very, very still, focusing intently on an interesting stain on the ceiling, as the Autodoc slices painlessly into you." ) );
2942 }
2943 }
2944
2945 //Pain junkies feel sorry about missed pain from operation.
2949 _( "As your consciousness slips away, you feel regret that you won't be able to enjoy the operation." ) );
2950 }
2951
2952 if( has_effect( effect_narcosis ) ) {
2953 const time_duration remaining_time = get_effect_dur( effect_narcosis );
2954 if( remaining_time <= duration ) {
2955 const time_duration top_off_time = duration - remaining_time;
2956 add_effect( effect_narcosis, top_off_time );
2957 fall_asleep( top_off_time );
2958 }
2959 } else {
2960 add_effect( effect_narcosis, duration );
2961 fall_asleep( duration );
2962 }
2963}
static const efftype_id effect_narcosis("narcosis")
static const trait_id trait_THRESH_MEDICAL("THRESH_MEDICAL")
static const trait_id trait_MASOCHIST_MED("MASOCHIST_MED")
static const trait_id trait_CENOBITE("CENOBITE")
static const trait_id trait_MASOCHIST("MASOCHIST")
void add_msg_player_or_npc(const std::string &player_msg, const std::string &npc_str) const override
Definition: player.cpp:371
void add_msg_if_player(const std::string &msg) const override
Definition: player.cpp:366

References _, Creature::add_effect(), Creature::add_msg_if_player(), player::add_msg_if_player(), Creature::add_msg_player_or_npc(), player::add_msg_player_or_npc(), effect_narcosis, fall_asleep(), Creature::get_effect_dur(), Creature::has_effect(), has_trait(), m_info, m_mixed, trait_CENOBITE, trait_DEBUG_BIONICS, trait_MASOCHIST, trait_MASOCHIST_MED, and trait_THRESH_MEDICAL.

Referenced by iexamine::autodoc().

◆ inv_dump()

std::vector< item * > Character::inv_dump ( )

Definition at line 8961 of file character.cpp.

8962{
8963 std::vector<item *> ret;
8964 if( is_armed() && can_unwield( primary_weapon() ).success() ) {
8965 ret.push_back( &primary_weapon() );
8966 }
8967 for( auto &i : worn ) {
8968 ret.push_back( &i );
8969 }
8970 inv.dump( ret );
8971 return ret;
8972}
void dump(std::vector< item * > &dest)
Definition: inventory.cpp:791

References can_unwield(), inventory::dump(), inv, is_armed(), primary_weapon(), cata::hash64_detail::ret, behavior::success, and worn.

Referenced by npc::apply_ownership_to_inv(), are_requirements_nearby(), npc::die(), generic_multi_activity_locations(), irradiate(), game::load(), item_action_generator::map_actions_to_items(), place_corpse(), conditional_t< T >::set_has_stolen_item(), sleep(), game::start_game(), and tidy_activity().

◆ invalidate_crafting_inventory()

◆ invlet_to_item()

item * Character::invlet_to_item ( int  invlet)

Return the item pointer of the item with given invlet, return nullptr if the player does not have such an item with that invlet.

Don't use this on npcs. Only use the invlet in the user interface, otherwise always use the item position.

Definition at line 2308 of file character.cpp.

2309{
2310 // Invlets may come from curses, which may also return any kind of key codes, those being
2311 // of type int and they can become valid, but different characters when casted to char.
2312 // Example: KEY_NPAGE (returned when the player presses the page-down key) is 0x152,
2313 // casted to char would yield 0x52, which happens to be 'R', a valid invlet.
2314 if( linvlet > std::numeric_limits<char>::max() || linvlet < std::numeric_limits<char>::min() ) {
2315 return nullptr;
2316 }
2317 const char invlet = static_cast<char>( linvlet );
2318 item *invlet_item = nullptr;
2319 visit_items( [&invlet, &invlet_item]( item * it ) {
2320 if( it->invlet == invlet ) {
2321 invlet_item = it;
2322 return VisitResponse::ABORT;
2323 }
2324 // Visit top-level items only as UIs don't support nested items.
2325 // Also, inventory restack logic depends on this.
2326 return VisitResponse::SKIP;
2327 } );
2328 return invlet_item;
2329}

References item::invlet, SKIP, and visitable< Character >::visit_items().

Referenced by pick_one_up(), game_menus::inv::reassign_letter(), inventory::restack(), show_armor_layers_ui(), and game_menus::inv::swap_letters().

◆ invoke_item() [1/4]

bool Character::invoke_item ( item used)
virtual

As above two, but with position equal to current position.

Reimplemented in avatar, npc, avatar, and npc.

Definition at line 7219 of file character.cpp.

7220{
7221 return invoke_item( used, pos() );
7222}

References invoke_item(), and pos().

◆ invoke_item() [2/4]

bool Character::invoke_item ( item used,
const std::string &  method 
)
virtual

Reimplemented in avatar, npc, avatar, and npc.

Definition at line 7229 of file character.cpp.

7230{
7231 return invoke_item( used, method, pos() );
7232}

References invoke_item(), and pos().

◆ invoke_item() [3/4]

bool Character::invoke_item ( item used,
const std::string &  method,
const tripoint pt 
)
virtual

As above, but with a pre-selected method.

Debugmsg if this item doesn't have this method.

Reimplemented in avatar, npc, and avatar.

Definition at line 7234 of file character.cpp.

7235{
7236 if( !has_enough_charges( *used, true ) ) {
7237 return false;
7238 }
7239
7240 item *actually_used = used->get_usable_item( method );
7241 if( actually_used == nullptr ) {
7242 debugmsg( "Tried to invoke a method %s on item %s, which doesn't have this method",
7243 method.c_str(), used->tname() );
7244 return false;
7245 }
7246
7247 int charges_used = actually_used->type->invoke( *this->as_player(), *actually_used, pt, method );
7248 if( charges_used == 0 ) {
7249 return false;
7250 }
7251 // Prevent accessing the item as it may have been deleted by the invoked iuse function.
7252
7253 if( used->is_tool() || used->is_medication() || used->get_contained().is_medication() ) {
7254 return consume_charges( *actually_used, charges_used );
7255 } else if( used->is_bionic() || used->is_deployable() || method == "place_trap" ) {
7256 i_rem( used );
7257 return true;
7258 }
7259
7260 return false;
7261}
bool has_enough_charges(const item &it, bool show_msg) const
Has the item enough charges to invoke its use function? Also checks if UPS from this player is used i...
Definition: character.cpp:7358
bool consume_charges(item &used, int qty)
Consume charges of a tool or comestible item, potentially destroying it in the process.
Definition: character.cpp:7413
bool is_deployable() const
Definition: item.cpp:6978
item * get_usable_item(const std::string &use_name)
Checks this item and its contents (recursively) for types that have use_function with type use_name.
Definition: item.cpp:7990
bool is_bionic() const
Definition: item.cpp:6577

References Creature::as_player(), consume_charges(), debugmsg, item::get_contained(), item::get_usable_item(), has_enough_charges(), i_rem(), itype::invoke(), item::is_bionic(), item::is_deployable(), item::is_medication(), item::is_tool(), item::tname(), and item::type.

◆ invoke_item() [4/4]

bool Character::invoke_item ( item ,
const tripoint pt 
)
virtual

Asks how to use the item (if it has more than one use_method) and uses it.

Returns true if it destroys the item. Consumes charges from the item. Multi-use items are ONLY supported when all use_methods are iuse_actor!

Reimplemented in avatar, npc, avatar, and npc.

Definition at line 7224 of file character.cpp.

7225{
7226 return false;
7227}

Referenced by activate_bionic(), activate_mutation(), invoke_item(), avatar::invoke_item(), npc::invoke_item(), and iexamine::use_furn_fake_item().

◆ irradiate()

bool Character::irradiate ( float  rads,
bool  bypass = false 
)

Handles mitigation and application of radiation.

Definition at line 1601 of file suffer.cpp.

1602{
1603 int rad_mut = 0;
1604 if( has_trait( trait_RADIOACTIVE3 ) ) {
1605 rad_mut = 3;
1606 } else if( has_trait( trait_RADIOACTIVE2 ) ) {
1607 rad_mut = 2;
1608 } else if( has_trait( trait_RADIOACTIVE1 ) ) {
1609 rad_mut = 1;
1610 }
1611
1612 if( rads > 0 ) {
1613 bool has_helmet = false;
1614 const bool power_armored = is_wearing_power_armor( &has_helmet );
1615 const bool rad_resist = power_armored || worn_with_flag( "RAD_RESIST" );
1616
1617 if( is_rad_immune() && !bypass ) {
1618 // Power armor and some high-tech gear protects completely from radiation
1619 rads = 0.0f;
1620 } else if( rad_resist && !bypass ) {
1621 rads /= 4.0f;
1622 }
1623
1624 if( has_effect( effect_iodine ) ) {
1625 // Radioactive mutation makes iodine less efficient (but more useful)
1626 rads *= 0.3f + 0.1f * rad_mut;
1627 }
1628
1629 int rads_max = roll_remainder( rads );
1630 mod_rad( rng( 0, rads_max ) );
1631
1632 // Apply rads to any radiation badges.
1633 for( item *const it : inv_dump() ) {
1634 if( it->typeId() != itype_rad_badge ) {
1635 continue;
1636 }
1637
1638 // Actual irradiation levels of badges and the player aren't precisely matched.
1639 // This is intentional.
1640 const int before = it->irradiation;
1641
1642 const int delta = rng( 0, rads_max );
1643 if( delta == 0 ) {
1644 continue;
1645 }
1646
1647 it->irradiation += delta;
1648
1649 // If in inventory (not worn), don't print anything.
1650 if( inv.has_item( *it ) ) {
1651 continue;
1652 }
1653
1654 // If the color hasn't changed, don't print anything.
1655 const std::string &col_before = rad_badge_color( before );
1656 const std::string &col_after = rad_badge_color( it->irradiation );
1657 if( col_before == col_after ) {
1658 continue;
1659 }
1660
1661 add_msg_if_player( m_warning, _( "Your radiation badge changes from %1$s to %2$s!" ),
1662 col_before, col_after );
1663 }
1664
1665 if( rads > 0.0f ) {
1666 return true;
1667 }
1668 }
1669 return false;
1670}
void mod_rad(int mod)
Definition: character.cpp:7078
std::vector< item * > inv_dump()
Definition: character.cpp:8961
bool is_rad_immune() const
Returns true if the player is protected from radiation.
Definition: character.cpp:6193
std::string rad_badge_color(const int rad)
Definition: item.cpp:292
static const trait_id trait_RADIOACTIVE2("RADIOACTIVE2")
static const trait_id trait_RADIOACTIVE3("RADIOACTIVE3")
static const trait_id trait_RADIOACTIVE1("RADIOACTIVE1")
static const itype_id itype_rad_badge("rad_badge")
static const efftype_id effect_iodine("iodine")

References _, Creature::add_msg_if_player(), effect_iodine, Creature::has_effect(), visitable< T >::has_item(), has_trait(), inv, inv_dump(), is_rad_immune(), is_wearing_power_armor(), itype_rad_badge, m_warning, mod_rad(), rad_badge_color(), rng(), roll_remainder(), trait_RADIOACTIVE1, trait_RADIOACTIVE2, trait_RADIOACTIVE3, and worn_with_flag().

Referenced by trapfunc::glow(), hardcoded_effects(), modify_radiation(), map::player_in_field(), game::process_artifact(), mattack::science(), and suffer_from_radiation().

◆ is_armed()

◆ is_auto_moving()

bool Character::is_auto_moving ( ) const

Definition at line 10507 of file character.cpp.

10508{
10509 return destination_point.has_value();
10510}

References destination_point.

Referenced by game::handle_action(), and avatar_action::move().

◆ is_blind()

bool Character::is_blind ( ) const

◆ is_category_allowed() [1/2]

bool Character::is_category_allowed ( const std::string &  category) const

Definition at line 394 of file mutation.cpp.

395{
396 bool allowed = false;
397 bool restricted = false;
398 for( const trait_id &mut : get_mutations() ) {
399 for( const std::string &Ch_cat : mut.obj().allowed_category ) {
400 restricted = true;
401 if( Ch_cat == category ) {
402 allowed = true;
403 }
404 }
405 }
406 if( !restricted ) {
407 allowed = true;
408 }
409 return allowed;
410}

References get_mutations().

◆ is_category_allowed() [2/2]

bool Character::is_category_allowed ( const std::vector< std::string > &  category) const

Returns true if this category of mutation is allowed.

Definition at line 371 of file mutation.cpp.

372{
373 bool allowed = false;
374 bool restricted = false;
375 for( const trait_id &mut : get_mutations() ) {
376 if( !mut.obj().allowed_category.empty() ) {
377 restricted = true;
378 }
379 for( const std::string &Mu_cat : category ) {
380 if( mut.obj().allowed_category.count( Mu_cat ) ) {
381 allowed = true;
382 break;
383 }
384 }
385
386 }
387 if( !restricted ) {
388 allowed = true;
389 }
390 return allowed;
391
392}

References get_mutations().

Referenced by mutation_ok(), and old_mutate().

◆ is_dead_state()

bool Character::is_dead_state ( ) const
overridevirtual

Returns true if the character should be dead.

Implements Creature.

Definition at line 499 of file character.cpp.

500{
501 const auto all_bps = get_all_body_parts( true );
502
503 return std::any_of( all_bps.begin(), all_bps.end(), [this]( const bodypart_id & bp ) {
504 return bp->essential && get_part_hp_cur( bp ) <= 0;
505 } );
506}

References Creature::get_all_body_parts().

Referenced by apply_damage(), block_hit(), game::do_turn(), game::handle_action(), hurtall(), npc::is_dead(), game::is_game_over(), on_dodge(), vehicle_part::set_crew(), npc::talk_to_u(), game::win(), and game::win_screen().

◆ is_deaf()

◆ is_elec_immune()

bool Character::is_elec_immune ( ) const
overridevirtual

Returns true is the player is protected from electric shocks.

Implements Creature.

Definition at line 6123 of file character.cpp.

6124{
6125 return is_immune_damage( DT_ELECTRIC );
6126}
bool is_immune_damage(damage_type) const override
Returns true if the player is immune to this kind of damage.
Definition: character.cpp:6150

References DT_ELECTRIC, and is_immune_damage().

Referenced by iuse::ehandcuffs(), is_immune_field(), and map::player_in_field().

◆ is_hauling()

bool Character::is_hauling ( ) const

Definition at line 9186 of file character.cpp.

9187{
9188 return hauling;
9189}
bool hauling
Definition: character.h:1574

References hauling.

Referenced by cancel_activity(), haul(), game::place_player(), avatar::set_movement_mode(), game::vertical_move(), and game::walk_move().

◆ is_hibernating()

bool Character::is_hibernating ( ) const

Returns if the player has hibernation mutation and is asleep and well fed.

Definition at line 5175 of file character.cpp.

References effect_sleep, get_kcal_percent(), get_thirst(), has_active_mutation(), Creature::has_effect(), trait_HIBERNATE, and very_thirsty.

Referenced by calc_needs_rates(), and update_needs().

◆ is_immune_damage()

bool Character::is_immune_damage ( damage_type  dt) const
overridevirtual

Returns true if the player is immune to this kind of damage.

Implements Creature.

Definition at line 6150 of file character.cpp.

6151{
6152 switch( dt ) {
6153 case DT_NULL:
6154 return true;
6155 case DT_TRUE:
6156 return false;
6157 case DT_BIOLOGICAL:
6158 return has_effect_with_flag( "EFFECT_BIO_IMMUNE" ) ||
6159 worn_with_flag( "BIO_IMMUNE" );
6160 case DT_BASH:
6161 return has_effect_with_flag( "EFFECT_BASH_IMMUNE" ) ||
6162 worn_with_flag( "BASH_IMMUNE" );
6163 case DT_CUT:
6164 return has_effect_with_flag( "EFFECT_CUT_IMMUNE" ) ||
6165 worn_with_flag( "CUT_IMMUNE" );
6166 case DT_ACID:
6167 return has_trait( trait_ACIDPROOF ) ||
6168 has_effect_with_flag( "EFFECT_ACID_IMMUNE" ) ||
6169 worn_with_flag( "ACID_IMMUNE" );
6170 case DT_STAB:
6171 return has_effect_with_flag( "EFFECT_STAB_IMMUNE" ) ||
6172 worn_with_flag( "STAB_IMMUNE" );
6173 case DT_BULLET:
6174 return has_effect_with_flag( "EFFECT_BULLET_IMMUNE" ) || worn_with_flag( "BULLET_IMMUNE" );
6175 case DT_HEAT:
6176 return has_trait( trait_M_SKIN2 ) ||
6178 has_effect_with_flag( "EFFECT_HEAT_IMMUNE" ) ||
6179 worn_with_flag( "HEAT_IMMUNE" );
6180 case DT_COLD:
6181 return has_effect_with_flag( "EFFECT_COLD_IMMUNE" ) ||
6182 worn_with_flag( "COLD_IMMUNE" );
6183 case DT_ELECTRIC:
6184 return has_active_bionic( bio_faraday ) ||
6185 worn_with_flag( "ELECTRIC_IMMUNE" ) ||
6187 has_effect_with_flag( "EFFECT_ELECTRIC_IMMUNE" );
6188 default:
6189 return true;
6190 }
6191}
static const trait_id trait_ACIDPROOF("ACIDPROOF")
static const trait_id trait_M_SKIN2("M_SKIN2")
static const bionic_id bio_faraday("bio_faraday")
@ AEP_RESIST_ELECTRICITY
Definition: enums.h:117

References AEP_RESIST_ELECTRICITY, bio_faraday, DT_ACID, DT_BASH, DT_BIOLOGICAL, DT_BULLET, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_NULL, DT_STAB, DT_TRUE, has_active_bionic(), has_artifact_with(), Creature::has_effect_with_flag(), has_trait(), trait_ACIDPROOF, trait_M_SKIN2, trait_M_SKIN3, and worn_with_flag().

Referenced by character_funcs::is_bp_immune_to(), is_elec_immune(), and is_immune_effect().

◆ is_immune_effect()

bool Character::is_immune_effect ( const efftype_id eff) const
overridevirtual

Returns true if the player is immune to this kind of effect.

Implements Creature.

Definition at line 6128 of file character.cpp.

6129{
6130 if( eff == effect_downed ) {
6132 } else if( eff == effect_onfire ) {
6133 return is_immune_damage( DT_HEAT );
6134 } else if( eff == effect_deaf ) {
6136 has_bionic( bio_ears ) ||
6138 } else if( eff == effect_corroding ) {
6140 } else if( eff == effect_nausea ) {
6142 } else if( eff == effect_bleed ) {
6143 // Ugly, it was badly implemented and should be a flag
6144 return mutation_value( "bleed_resist" ) > 0.0f;
6145 }
6146
6147 return false;
6148}
static const trait_id trait_SLIMY("SLIMY")
static const trait_id trait_LEG_TENT_BRACE("LEG_TENT_BRACE")
static const trait_id trait_STRONGSTOMACH("STRONGSTOMACH")
static const itype_id itype_rm13_armor_on("rm13_armor_on")
static const efftype_id effect_corroding("corroding")
static const trait_id trait_VISCOUS("VISCOUS")
static const std::string flag_PARTIAL_DEAF("PARTIAL_DEAF")
static const efftype_id effect_nausea("nausea")
double footwear_factor() const
Returns 1 if the player is wearing something on both feet, .5 if on one, and 0 if on neither.
Definition: character.cpp:8937
bool is_throw_immune() const
Returns true if the player is immune to throws.

References bio_ears, DT_ACID, DT_HEAT, effect_bleed, effect_corroding, effect_deaf, effect_downed, effect_nausea, effect_onfire, flag_DEAF(), flag_PARTIAL_DEAF(), footwear_factor(), has_bionic(), has_trait(), is_immune_damage(), is_throw_immune(), is_wearing(), itype_rm13_armor_on, mutation_value(), trait_LEG_TENT_BRACE, trait_SLIMY, trait_STRONGSTOMACH, trait_VISCOUS, and worn_with_flag().

Referenced by sounds::process_sound_markers().

◆ is_immune_field()

bool Character::is_immune_field ( const field_type_id ) const
overridevirtual

Returns true if we are immune to the field type with the given fid.

Does not handle intensity, so this function should only be called through is_dangerous_field().

Reimplemented from Creature.

Definition at line 6082 of file character.cpp.

6083{
6084 // Obviously this makes us invincible
6085 if( has_trait( trait_DEBUG_NODMG ) ) {
6086 return true;
6087 }
6088 // Check to see if we are immune
6089 const field_type &ft = fid.obj();
6090 for( const trait_id &t : ft.immunity_data_traits ) {
6091 if( has_trait( t ) ) {
6092 return true;
6093 }
6094 }
6095 bool immune_by_body_part_resistance = !ft.immunity_data_body_part_env_resistance.empty();
6096 for( const std::pair<body_part, int> &fide : ft.immunity_data_body_part_env_resistance ) {
6097 immune_by_body_part_resistance = immune_by_body_part_resistance &&
6098 get_env_resist( convert_bp( fide.first ).id() ) >= fide.second;
6099 }
6100 if( immune_by_body_part_resistance ) {
6101 return true;
6102 }
6103 if( ft.has_elec ) {
6104 return is_elec_immune();
6105 }
6106 if( ft.has_fire ) {
6108 }
6109 if( ft.has_acid ) {
6110 return !is_on_ground() && get_env_resist( bodypart_id( "foot_l" ) ) >= 15 &&
6111 get_env_resist( bodypart_id( "foot_r" ) ) >= 15 &&
6112 get_env_resist( bodypart_id( "leg_l" ) ) >= 15 &&
6113 get_env_resist( bodypart_id( "leg_r" ) ) >= 15 &&
6114 get_armor_type( DT_ACID, bodypart_id( "foot_l" ) ) >= 5 &&
6115 get_armor_type( DT_ACID, bodypart_id( "foot_r" ) ) >= 5 &&
6116 get_armor_type( DT_ACID, bodypart_id( "leg_l" ) ) >= 5 &&
6117 get_armor_type( DT_ACID, bodypart_id( "leg_r" ) ) >= 5;
6118 }
6119 // If we haven't found immunity yet fall up to the next level
6120 return Creature::is_immune_field( fid );
6121}
static const bionic_id bio_heatsink("bio_heatsink")
bool is_elec_immune() const override
Returns true is the player is protected from electric shocks.
Definition: character.cpp:6123
bool is_on_ground() const override
Returns true if the player is knocked over or has broken legs.
Definition: character.cpp:897
int get_env_resist(bodypart_id bp) const override
Returns overall env_resist on a body_part.
Definition: character.cpp:7025
virtual bool is_immune_field(const field_type_id &) const
Returns true if we are immune to the field type with the given fid.
Definition: creature.h:331
std::vector< trait_id > immunity_data_traits
Definition: field_type.h:172
bool has_elec
Definition: field_type.h:164
bool has_acid
Definition: field_type.h:163
bool has_fire
Definition: field_type.h:162
std::vector< std::pair< body_part, int > > immunity_data_body_part_env_resistance
Definition: field_type.h:173

References bio_heatsink, convert_bp(), DT_ACID, get_armor_type(), get_env_resist(), field_type::has_acid, has_active_bionic(), field_type::has_elec, field_type::has_fire, has_trait(), string_id< T >::id(), field_type::immunity_data_body_part_env_resistance, field_type::immunity_data_traits, is_elec_immune(), Creature::is_immune_field(), is_on_ground(), is_wearing(), itype_rm13_armor_on, int_id< T >::obj(), and trait_DEBUG_NODMG.

◆ is_invisible()

bool Character::is_invisible ( ) const

Definition at line 6281 of file character.cpp.

6282{
6283 return (
6288 );
6289}
static const std::string flag_EFFECT_INVISIBLE("EFFECT_INVISIBLE")

References AEP_INVISIBLE, flag_EFFECT_INVISIBLE(), has_artifact_with(), Creature::has_effect_with_flag(), has_trait(), is_wearing_active_optcloak(), and trait_DEBUG_CLOAK.

Referenced by visibility().

◆ is_limb_broken()

bool Character::is_limb_broken ( const bodypart_id limb) const

◆ is_limb_disabled()

bool Character::is_limb_disabled ( const bodypart_id limb) const

Returns true if the limb is disabled(12.5% or less hp)

Definition at line 1257 of file character.cpp.

1258{
1259 return get_part_hp_cur( limb ) <= get_part_hp_max( limb ) * .125;
1260}

References Creature::get_part_hp_cur(), and Creature::get_part_hp_max().

Referenced by best_shield(), and get_working_arm_count().

◆ is_limb_hindered()

bool Character::is_limb_hindered ( hp_part  limb) const

Returns true if the limb is hindered(40% or less hp)

◆ is_max_power()

bool Character::is_max_power ( ) const

Definition at line 1941 of file character.cpp.

1942{
1943 return power_level >= max_power_level;
1944}

References max_power_level, and power_level.

Referenced by feed_furnace_with().

◆ is_mounted()

bool Character::is_mounted ( ) const

Definition at line 1082 of file character.cpp.

1083{
1085}

References effect_riding, Creature::has_effect(), and mounted_creature.

Referenced by activate_bionic(), cata_event_dispatch::avatar_moves(), best_nearby_lifting_assist(), iuse::blood_draw(), iuse::boltcutters(), iuse::burrow(), can_install_bionics(), map::can_move_furniture(), cauterize_actor::can_use(), enzlave_actor::can_use(), musical_instrument_actor::can_use(), install_bionic_actor::can_use(), repair_item_actor::can_use_tool(), can_wield(), iuse::capture_monster_act(), iuse::capture_monster_veh(), debug_menu::character_edit_menu(), check_mount_is_spooked(), check_mount_will_move(), iuse::chop_logs(), iuse::chop_tree(), iuse::clear_rubble(), iuse::craft(), iuse::crowbar(), iuse::cut_log_into_planks(), npc::die(), iuse::dig(), iuse::dig_channel(), iuse::disassemble(), dismount(), game::do_turn(), iuse::einktabletpc(), game::examine(), iuse::fill_pit(), ranged::fire_gun(), iuse::fish_trap(), iuse::fishing_rod(), game::grabbed_furn_move(), game::grabbed_veh_move(), iuse::gun_repair(), ranged::gunmode_checks_weapon(), iuse::hacksaw(), iuse::hairkit(), iuse::hammer(), game::handle_action(), has_charges(), iuse::jackhammer(), iuse::ladder(), character_funcs::list_ammo(), iuse::lumber(), iuse::makemound(), iuse::meditate(), melee_attack(), iuse::mind_splicer(), mine_activity(), iuse::mop(), avatar_action::move(), npc::move_to(), game::npc_menu(), game::on_move_effects(), map::open_door(), overmap_sight_range(), iuse::oxytorch(), perform_technique(), iuse::pickaxe(), npc::place_on_map(), game::place_player(), game::place_player_overmap(), avatar_action::plthrow(), iuse::portable_game(), iuse::portal(), game::prompt_dangerous_tile(), recalc_sight_limits(), reset_stats(), iuse::rpgdie(), run_cost(), avatar::set_movement_mode(), iuse::shavekit(), iuse::siphon(), sleep(), smash(), store(), avatar_action::swim(), swim_speed(), iuse::teleport(), ranged::throw_item(), throw_range(), trapfunc::tripwire(), iuse::unfold_generic(), unfold_vehicle_iuse::use(), pick_lock_actor::use(), deploy_furn_actor::use(), cauterize_actor::use(), enzlave_actor::use(), musical_instrument_actor::use(), heal_actor::use(), place_trap_actor::use(), deploy_tent_actor::use(), sew_advanced_actor::use(), weigh_self_actor::use(), use_charges(), game::vertical_move(), iuse::vibe(), game::walk_move(), iuse::wash_hard_items(), wash_items(), iuse::wash_soft_items(), iuse::water_purifier(), weight_capacity(), and npc::worker_downtime().

◆ is_on_ground()

bool Character::is_on_ground ( ) const
overridevirtual

Returns true if the player is knocked over or has broken legs.

Implements Creature.

Definition at line 897 of file character.cpp.

898{
900}

References effect_downed, get_working_leg_count(), and Creature::has_effect().

Referenced by is_immune_field(), map::player_in_field(), and game::walk_move().

◆ is_quiet()

bool Character::is_quiet ( ) const

Returns true if the player has quiet melee attacks.

Definition at line 1222 of file martialarts.cpp.

1223{
1224 return search_ma_buff_effect( *effects, []( const ma_buff & b, const effect & ) {
1225 return b.is_quiet();
1226 } );
1227}

References b, Creature::effects, and search_ma_buff_effect().

Referenced by melee_attack().

◆ is_rad_immune()

bool Character::is_rad_immune ( ) const

Returns true if the player is protected from radiation.

Definition at line 6193 of file character.cpp.

6194{
6195 bool has_helmet = false;
6196 return ( is_wearing_power_armor( &has_helmet ) && has_helmet ) || worn_with_flag( "RAD_PROOF" );
6197}

References is_wearing_power_armor(), and worn_with_flag().

Referenced by irradiate(), and suffer_from_radiation().

◆ is_snuggling()

std::string Character::is_snuggling ( ) const

Checks to see if the player is using floor items to keep warm, and return the name of one such item if so.

Definition at line 9327 of file character.cpp.

9328{
9329 map &here = get_map();
9330 auto begin = here.i_at( pos() ).begin();
9331 auto end = here.i_at( pos() ).end();
9332
9333 if( in_vehicle ) {
9334 if( const std::optional<vpart_reference> vp = here.veh_at( pos() ).part_with_feature( VPFLAG_CARGO,
9335 false ) ) {
9336 vehicle *const veh = &vp->vehicle();
9337 const int cargo = vp->part_index();
9338 if( !veh->get_items( cargo ).empty() ) {
9339 begin = veh->get_items( cargo ).begin();
9340 end = veh->get_items( cargo ).end();
9341 }
9342 }
9343 }
9344 const item *floor_armor = nullptr;
9345 int ticker = 0;
9346
9347 // If there are no items on the floor, return nothing
9348 if( begin == end ) {
9349 return "nothing";
9350 }
9351
9352 for( auto candidate = begin; candidate != end; ++candidate ) {
9353 if( !candidate->is_armor() ) {
9354 continue;
9355 } else if( candidate->volume() > 250_ml && candidate->get_warmth() > 0 &&
9356 ( candidate->covers( bp_torso ) || candidate->covers( bp_leg_l ) ||
9357 candidate->covers( bp_leg_r ) ) ) {
9358 floor_armor = &*candidate;
9359 ticker++;
9360 }
9361 }
9362
9363 if( ticker == 0 ) {
9364 return "nothing";
9365 } else if( ticker == 1 ) {
9366 return floor_armor->type_name();
9367 } else if( ticker > 1 ) {
9368 return "many";
9369 }
9370
9371 return "nothing";
9372}
bool in_vehicle
Definition: character.h:1573
bool empty() const
Definition: item_stack.cpp:15

References item_stack::begin(), bp_leg_l, bp_leg_r, bp_torso, item_stack::empty(), item_stack::end(), vehicle::get_items(), get_map(), map::i_at(), in_vehicle, pos(), item::type_name(), map::veh_at(), vehicle::vehicle(), and VPFLAG_CARGO.

Referenced by fall_asleep().

◆ is_stealthy()

bool Character::is_stealthy ( ) const

Returns true if the player has stealthy movement.

Definition at line 1228 of file martialarts.cpp.

1229{
1230 return search_ma_buff_effect( *effects, []( const ma_buff & b, const effect & ) {
1231 return b.is_stealthy();
1232 } );
1233}

References b, Creature::effects, and search_ma_buff_effect().

Referenced by game::walk_move().

◆ is_throw_immune()

bool Character::is_throw_immune ( ) const

Returns true if the player is immune to throws.

Definition at line 1216 of file martialarts.cpp.

1217{
1218 return search_ma_buff_effect( *effects, []( const ma_buff & b, const effect & ) {
1219 return b.is_throw_immune();
1220 } );
1221}

References b, Creature::effects, and search_ma_buff_effect().

Referenced by mattack::bio_op_takedown(), mattack::grab(), is_immune_effect(), mattack::thrown_by_judo(), and game::update_stair_monsters().

◆ is_visible_in_range()

bool Character::is_visible_in_range ( const Creature critter,
int  range 
) const
private

Check whether the other creature is in range and can be seen by this creature.

Parameters
critterCreature to check for visibility
rangeThe maximal distance (rl_dist), creatures at this distance or less are included.

Definition at line 10224 of file character.cpp.

10225{
10226 return sees( critter ) && rl_dist( pos(), critter.pos() ) <= range;
10227}

References Creature::pos(), pos(), range, rl_dist(), and sees().

◆ is_warm()

bool Character::is_warm ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 534 of file character.cpp.

535{
536 // TODO: is there a mutation (plant?) that makes a npc not warm blooded?
537 return true;
538}

◆ is_waterproof()

bool Character::is_waterproof ( const body_part_set parts) const

Definition at line 8997 of file character.cpp.

8998{
8999 return covered_with_flag( "WATERPROOF", parts );
9000}
bool covered_with_flag(const std::string &flag, const body_part_set &parts) const
Definition: character.cpp:8974

References covered_with_flag().

Referenced by drench().

◆ is_weak_to_water()

bool Character::is_weak_to_water ( ) const

Definition at line 412 of file mutation.cpp.

413{
414 for( const trait_id &mut : get_mutations() ) {
415 if( mut.obj().weakness_to_water > 0 ) {
416 return true;
417 }
418 }
419 return false;
420}

References get_mutations().

Referenced by drench().

◆ is_wearing() [1/2]

◆ is_wearing() [2/2]

bool Character::is_wearing ( const itype_id it) const

Returns true if the player is wearing an item of this type.

Definition at line 3244 of file character.cpp.

3245{
3246 for( auto &i : worn ) {
3247 if( i.typeId() == it ) {
3248 return true;
3249 }
3250 }
3251 return false;
3252}

References worn.

◆ is_wearing_active_optcloak()

bool Character::is_wearing_active_optcloak ( ) const

Returns true if the player is wearing an active optical cloak.

Definition at line 3842 of file character.cpp.

3843{
3844 for( auto &w : worn ) {
3845 if( w.active && w.has_flag( flag_ACTIVE_CLOAKING ) ) {
3846 return true;
3847 }
3848 }
3849 return false;
3850}
static const std::string flag_ACTIVE_CLOAKING("ACTIVE_CLOAKING")

References flag_ACTIVE_CLOAKING(), and worn.

Referenced by basic_symbol_color(), and is_invisible().

◆ is_wearing_active_power_armor()

bool Character::is_wearing_active_power_armor ( ) const

Returns true if the character is wearing active power.

Definition at line 3832 of file character.cpp.

3833{
3834 for( const auto &w : worn ) {
3835 if( w.has_flag( flag_POWERARMOR_EXO ) && w.active ) {
3836 return true;
3837 }
3838 }
3839 return false;
3840}

References flag_POWERARMOR_EXO(), and worn.

◆ is_wearing_helmet()

bool Character::is_wearing_helmet ( ) const

Returns true if the character is wearing something occupying the helmet slot.

Definition at line 8900 of file character.cpp.

8901{
8902 for( const item &i : worn ) {
8903 if( i.covers( bp_head ) && !i.has_flag( flag_HELMET_COMPAT ) && !i.has_flag( flag_SKINTIGHT ) &&
8904 !i.has_flag( flag_PERSONAL ) && !i.has_flag( flag_AURA ) && !i.has_flag( flag_SEMITANGIBLE ) &&
8905 !i.has_flag( flag_OVERSIZE ) ) {
8906 return true;
8907 }
8908 }
8909 return false;
8910}

References bp_head, flag_AURA(), flag_HELMET_COMPAT(), flag_OVERSIZE(), flag_PERSONAL(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), and worn.

Referenced by can_wear().

◆ is_wearing_on_bp()

bool Character::is_wearing_on_bp ( const itype_id it,
const bodypart_id bp 
) const

Returns true if the player is wearing the item on the given body part.

Definition at line 3254 of file character.cpp.

3255{
3256 for( auto &i : worn ) {
3257 if( i.typeId() == it && i.covers( bp->token ) ) {
3258 return true;
3259 }
3260 }
3261 return false;
3262}

References worn.

Referenced by shoe_type_count().

◆ is_wearing_power_armor()

bool Character::is_wearing_power_armor ( bool *  hasHelmet = nullptr) const

Returns true if the character is wearing power armor.

Definition at line 3807 of file character.cpp.

3808{
3809 bool result = false;
3810 for( auto &elem : worn ) {
3811 if( !elem.is_power_armor() ) {
3812 continue;
3813 }
3814 if( elem.has_flag( flag_POWERARMOR_EXO ) ) {
3815 result = true;
3816 if( hasHelmet == nullptr ) {
3817 // found power armor, helmet not requested, cancel loop
3818 return true;
3819 }
3820 }
3821 // found power armor, continue search for helmet
3822 if( elem.covers( bp_head ) ) {
3823 if( hasHelmet != nullptr ) {
3824 *hasHelmet = true;
3825 }
3826 return true;
3827 }
3828 }
3829 return result;
3830}

References bp_head, flag_POWERARMOR_EXO(), and worn.

Referenced by can_wear(), irradiate(), is_rad_immune(), power_rating(), and suffer_from_radiation().

◆ is_wearing_shoes()

bool Character::is_wearing_shoes ( const side which_side = side::BOTH) const

Returns true if the player is wearing something on their feet that is not SKINTIGHT.

Definition at line 8871 of file character.cpp.

8872{
8873 bool left = true;
8874 bool right = true;
8875 if( which_side == side::LEFT || which_side == side::BOTH ) {
8876 left = false;
8877 for( const item &worn_item : worn ) {
8878 if( worn_item.covers( bp_foot_l ) && !worn_item.has_flag( flag_BELTED ) &&
8879 !worn_item.has_flag( flag_PERSONAL ) && !worn_item.has_flag( flag_AURA ) &&
8880 !worn_item.has_flag( flag_SEMITANGIBLE ) && !worn_item.has_flag( flag_SKINTIGHT ) ) {
8881 left = true;
8882 break;
8883 }
8884 }
8885 }
8886 if( which_side == side::RIGHT || which_side == side::BOTH ) {
8887 right = false;
8888 for( const item &worn_item : worn ) {
8889 if( worn_item.covers( bp_foot_r ) && !worn_item.has_flag( flag_BELTED ) &&
8890 !worn_item.has_flag( flag_PERSONAL ) && !worn_item.has_flag( flag_AURA ) &&
8891 !worn_item.has_flag( flag_SEMITANGIBLE ) && !worn_item.has_flag( flag_SKINTIGHT ) ) {
8892 right = true;
8893 break;
8894 }
8895 }
8896 }
8897 return ( left && right );
8898}

References BOTH, bp_foot_l, bp_foot_r, flag_AURA(), flag_BELTED(), flag_PERSONAL(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), LEFT, left, RIGHT, right, and worn.

Referenced by can_wear(), rooted_message(), and suffer_from_other_mutations().

◆ is_wielding()

◆ is_worn()

◆ item_encumb()

void Character::item_encumb ( char_encumbrance_data vals,
const item new_item 
) const
protected

Applies encumbrance from items only If new_item is not null, then calculate under the asumption that it is added to existing work items.

Definition at line 3982 of file character.cpp.

3983{
3984
3985 // reset all layer data
3986 vals = char_encumbrance_data();
3987
3988 // Figure out where new_item would be worn
3989 std::list<item>::const_iterator new_item_position = worn.end();
3990 if( !new_item.is_null() ) {
3991 // const_cast required to work around g++-4.8 library bug
3992 // see the commit that added this comment to understand why
3993 new_item_position =
3994 const_cast<Character *>( this )->position_to_wear_new_item( new_item );
3995 }
3996
3997 // Track highest layer observed so far so we can penalize out-of-order
3998 // items
3999 std::array<layer_level, num_bp> highest_layer_so_far;
4000 std::fill( highest_layer_so_far.begin(), highest_layer_so_far.end(),
4002
4003 for( auto w_it = worn.begin(); w_it != worn.end(); ++w_it ) {
4004 if( w_it == new_item_position ) {
4005 layer_item( vals, new_item, highest_layer_so_far, *this );
4006 }
4007 layer_item( vals, *w_it, highest_layer_so_far, *this );
4008 }
4009
4010 if( worn.end() == new_item_position && !new_item.is_null() ) {
4011 layer_item( vals, new_item, highest_layer_so_far, *this );
4012 }
4013
4014 // make sure values are sane
4015 for( const body_part bp : all_body_parts ) {
4016 encumbrance_data &elem = vals.elems[bp];
4017
4018 elem.armor_encumbrance = std::max( 0, elem.armor_encumbrance );
4019
4020 // Add armor and layering penalties for the final values
4021 elem.encumbrance += elem.armor_encumbrance + elem.layer_penalty;
4022 }
4023}
static void layer_item(char_encumbrance_data &vals, const item &it, std::array< layer_level, num_bp > &highest_layer_so_far, const Character &c)
Definition: character.cpp:3765
std::list< item >::iterator position_to_wear_new_item(const item &new_item)
Return the position in the worn list where new_item would be put by default.
Definition: character.cpp:3953
@ PERSONAL_LAYER
Definition: enums.h:216
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t< Char > &fill)
std::array< encumbrance_data, num_bp > elems

References all_body_parts, encumbrance_data::armor_encumbrance, char_encumbrance_data::elems, encumbrance_data::encumbrance, detail::fill(), item::is_null(), layer_item(), encumbrance_data::layer_penalty, PERSONAL_LAYER, position_to_wear_new_item(), and worn.

Referenced by calc_encumbrance().

◆ item_handling_cost()

int Character::item_handling_cost ( const item it,
bool  penalties = true,
int  base_cost = INVENTORY_HANDLING_PENALTY 
) const

Calculate (but do not deduct) the number of moves required when handling (e.g.

storing, drawing etc.) an item

Parameters
itItem to calculate handling cost for
penaltiesWhether item volume and temporary effects (e.g. GRABBED, DOWNED) should be considered.
base_costCost due to storage type.
Returns
cost in moves ranging from 0 to MAX_HANDLING_COST

Definition at line 7470 of file character.cpp.

7471{
7472 int mv = base_cost;
7473 if( penalties ) {
7474 // 40 moves per liter, up to 200 at 5 liters
7475 mv += std::min( 200, it.volume() / 20_ml );
7476 }
7477
7478 const item &weapon = primary_weapon();
7479 if( weapon.typeId() == itype_e_handcuffs ) {
7480 mv *= 4;
7481 } else if( penalties && has_effect( effect_grabbed ) ) {
7482 mv *= 2;
7483 }
7484
7485 // For single handed items use the least encumbered hand
7486 if( it.is_two_handed( *this ) ) {
7487 mv += encumb( bp_hand_l ) + encumb( bp_hand_r );
7488 } else {
7489 mv += std::min( encumb( bp_hand_l ), encumb( bp_hand_r ) );
7490 }
7491
7492 return std::min( std::max( mv, 0 ), MAX_HANDLING_COST );
7493}
static const itype_id itype_e_handcuffs("e_handcuffs")
static constexpr int MAX_HANDLING_COST

References bp_hand_l, bp_hand_r, effect_grabbed, encumb(), Creature::has_effect(), item::is_two_handed(), itype_e_handcuffs, MAX_HANDLING_COST, primary_weapon(), item::typeId(), and item::volume().

Referenced by dispose_item(), npc::dispose_item(), throw_activity_actor::do_turn(), item_reload_cost(), item_store_cost(), item_wear_cost(), mill_activate(), mill_load_food(), iexamine::quern_examine(), smoker_activate(), smoker_load_food(), iexamine::smoker_options(), character_funcs::try_wield_contents(), avatar_funcs::unload_item(), and avatar::wield().

◆ item_reload_cost()

int Character::item_reload_cost ( const item it,
const item ammo,
int  qty 
) const

Calculate (but do not deduct) the number of moves required to reload an item with specified quantity of ammo.

Parameters
itItem to calculate reload cost for
ammoeither ammo or magazine to use when reloading the item
qtymaximum units of ammo to reload. Capped by remaining capacity and ignored if reloading using a magazine.
Gun decreases the time taken to reload a magazine Pistol decreases time taken to reload a pistol Smg decreases time taken to reload an SMG Rifle decreases time taken to reload a rifle Shotgun decreases time taken to reload a shotgun Launcher decreases time taken to reload a launcher Strength reduces reload time of some weapons

Definition at line 11080 of file character.cpp.

11081{
11082 if( ammo.is_ammo() ) {
11083 qty = std::max( std::min( ammo.charges, qty ), 1 );
11084 } else if( ammo.is_ammo_container() || ammo.is_container() ) {
11085 qty = clamp( qty, ammo.contents.front().charges, 1 );
11086 } else if( ammo.is_magazine() ) {
11087 qty = 1;
11088 } else {
11089 debugmsg( "cannot determine reload cost as %s is neither ammo or magazine", ammo.tname() );
11090 return 0;
11091 }
11092
11093 // If necessary create duplicate with appropriate number of charges
11094 item obj = ammo;
11095 obj = obj.split( qty );
11096 if( obj.is_null() ) {
11097 obj = ammo;
11098 }
11099 // No base cost for handling ammo - that's already included in obtain cost
11100 // We have the ammo in our hands right now
11101 int mv = item_handling_cost( obj, true, 0 );
11102
11103 if( ammo.has_flag( "MAG_BULKY" ) ) {
11104 mv *= 1.5; // bulky magazines take longer to insert
11105 }
11106
11107 if( !it.is_gun() && !it.is_magazine() ) {
11108 return mv + 100; // reload a tool or sealable container
11109 }
11110
11111 /** @EFFECT_GUN decreases the time taken to reload a magazine */
11112 /** @EFFECT_PISTOL decreases time taken to reload a pistol */
11113 /** @EFFECT_SMG decreases time taken to reload an SMG */
11114 /** @EFFECT_RIFLE decreases time taken to reload a rifle */
11115 /** @EFFECT_SHOTGUN decreases time taken to reload a shotgun */
11116 /** @EFFECT_LAUNCHER decreases time taken to reload a launcher */
11117
11118 int cost = ( it.is_gun() ? it.get_reload_time() : it.type->magazine->reload_time ) * qty;
11119
11120 skill_id sk = it.is_gun() ? it.type->gun->skill_used : skill_gun;
11121 mv += cost / ( 1.0f + std::min( get_skill_level( sk ) * 0.1f, 1.0f ) );
11122
11123 if( it.has_flag( "STR_RELOAD" ) ) {
11124 /** @EFFECT_STR reduces reload time of some weapons */
11125 mv -= get_str() * 20;
11126 }
11127
11128 return std::max( mv, 25 );
11129}
static const skill_id skill_gun("gun")
item split(int qty)
Splits a count-by-charges item always leaving source item with minimum of 1 charge.
Definition: item.cpp:724
int get_reload_time() const
Returns the reload time of the gun.
Definition: item.cpp:6553
bool is_magazine() const
Definition: item.cpp:6582
cata::value_ptr< islot_gun > gun
Definition: itype.h:827

References item::charges, clamp(), item::contents, debugmsg, item_contents::front(), item::get_reload_time(), get_skill_level(), get_str(), itype::gun, item::has_flag(), item::is_ammo(), item::is_ammo_container(), item::is_container(), item::is_gun(), item::is_magazine(), item::is_null(), item_handling_cost(), itype::magazine, skill_gun, item::split(), item::tname(), and item::type.

Referenced by npc::do_reload(), npc::enough_time_to_reload(), item_reload_option::moves(), and avatar_funcs::unload_item().

◆ item_store_cost()

int Character::item_store_cost ( const item it,
const item container,
bool  penalties = true,
int  base_cost = INVENTORY_HANDLING_PENALTY 
) const

Calculate (but do not deduct) the number of moves required when storing an item in a container.

Parameters
itItem to calculate storage cost for
containerContainer to store item in
penaltiesWhether item volume and temporary effects (e.g. GRABBED, DOWNED) should be considered.
base_costCost due to storage type.
Returns
cost in moves ranging from 0 to MAX_HANDLING_COST
Pistol decreases time taken to store a pistol Smg decreases time taken to store an SMG Rifle decreases time taken to store a rifle Shotgun decreases time taken to store a shotgun Launcher decreases time taken to store a launcher Stabbing decreases time taken to store a stabbing weapon Cutting decreases time taken to store a cutting weapon Bashing decreases time taken to store a bashing weapon

Definition at line 7495 of file character.cpp.

7497{
7498 /** @EFFECT_PISTOL decreases time taken to store a pistol */
7499 /** @EFFECT_SMG decreases time taken to store an SMG */
7500 /** @EFFECT_RIFLE decreases time taken to store a rifle */
7501 /** @EFFECT_SHOTGUN decreases time taken to store a shotgun */
7502 /** @EFFECT_LAUNCHER decreases time taken to store a launcher */
7503 /** @EFFECT_STABBING decreases time taken to store a stabbing weapon */
7504 /** @EFFECT_CUTTING decreases time taken to store a cutting weapon */
7505 /** @EFFECT_BASHING decreases time taken to store a bashing weapon */
7506 int lvl = get_skill_level( it.is_gun() ? it.gun_skill() : it.melee_skill() );
7507 return item_handling_cost( it, penalties, base_cost ) / ( ( lvl + 10.0f ) / 10.0f );
7508}
skill_id gun_skill() const
The skill used to operate the gun.
Definition: item.cpp:7212

References get_skill_level(), item::gun_skill(), item::is_gun(), item_handling_cost(), and item::melee_skill().

Referenced by dispose_item(), npc::dispose_item(), and character_funcs::store_in_container().

◆ item_wear_cost()

int Character::item_wear_cost ( const item it) const

Calculate (but do not deduct) the number of moves required to wear an item.

Definition at line 7510 of file character.cpp.

7511{
7512 double mv = item_handling_cost( it );
7513
7514 switch( it.get_layer() ) {
7515 case PERSONAL_LAYER:
7516 break;
7517
7518 case UNDERWEAR_LAYER:
7519 mv *= 1.5;
7520 break;
7521
7522 case REGULAR_LAYER:
7523 break;
7524
7525 case WAIST_LAYER:
7526 case OUTER_LAYER:
7527 mv /= 1.5;
7528 break;
7529
7530 case BELTED_LAYER:
7531 mv /= 2.0;
7532 break;
7533
7534 case AURA_LAYER:
7535 break;
7536
7537 default:
7538 break;
7539 }
7540
7541 mv *= std::max( it.get_encumber( *this ) / 10.0, 1.0 );
7542
7543 return mv;
7544}
layer_level get_layer() const
Returns clothing layer for item.
Definition: item.cpp:5900
@ WAIST_LAYER
Definition: enums.h:222
@ UNDERWEAR_LAYER
Definition: enums.h:218
@ REGULAR_LAYER
Definition: enums.h:220
@ BELTED_LAYER
Definition: enums.h:226
@ AURA_LAYER
Definition: enums.h:228
@ OUTER_LAYER
Definition: enums.h:224

References AURA_LAYER, BELTED_LAYER, item::get_encumber(), item::get_layer(), item_handling_cost(), OUTER_LAYER, PERSONAL_LAYER, REGULAR_LAYER, UNDERWEAR_LAYER, and WAIST_LAYER.

Referenced by dispose_item(), and wear_item().

◆ item_with_best_of_quality()

item & Character::item_with_best_of_quality ( const quality_id qid)

Returns the item in the player's inventory with the highest of the specified quality.

Definition at line 10012 of file character.cpp.

10013{
10014 int maxq = max_quality( qid );
10015 auto items_with_quality = items_with( [qid]( const item & it ) {
10016 return it.has_quality( qid );
10017 } );
10018 for( item *it : items_with_quality ) {
10019 if( it->get_quality( qid ) == maxq ) {
10020 return *it;
10021 }
10022 }
10023 return null_item_reference();
10024}
int get_quality(const quality_id &id) const
Definition: item.cpp:5408

References item::get_quality(), visitable< T >::has_quality(), visitable< Character >::items_with(), visitable< Character >::max_quality(), and null_item_reference().

◆ item_worn_with_flag()

const item * Character::item_worn_with_flag ( const std::string &  flag,
const bodypart_id bp = bodypart_str_id::NULL_ID() 
) const

Returns the first worn item with a given flag.

Definition at line 3272 of file character.cpp.

3273{
3274 for( const item &it : worn ) {
3275 if( it.has_flag( flag ) && ( bp == bodypart_str_id::NULL_ID() ||
3276 it.covers( bp->token ) ) ) {
3277 return &it;
3278 }
3279 }
3280 return nullptr;
3281}

References string_id< body_part_type >::NULL_ID(), and worn.

Referenced by burn_fuel().

◆ knock_back_to()

void Character::knock_back_to ( const tripoint to)
overridevirtual

Knocks the character to a specified tile.

Maximum Strength allows knocked back player to knock back, damage, stun some monsters

Implements Creature.

Definition at line 10968 of file character.cpp.

10969{
10970 if( to == pos() ) {
10971 return;
10972 }
10973
10974 if( rl_dist( pos(), to ) < 2 && get_map().obstructed_by_vehicle_rotation( pos(), to ) ) {
10975 tripoint intervening = to;
10976 if( one_in( 2 ) ) {
10977 intervening.x = pos().x;
10978 } else {
10979 intervening.y = pos().y;
10980 }
10981
10982 apply_damage( nullptr, bodypart_id( "torso" ), 3 );
10983 add_effect( effect_stunned, 2_turns );
10984 add_msg_player_or_npc( _( "You bounce off a %s!" ), _( "<npcname> bounces off a %s!" ),
10985 g->m.obstacle_name( intervening ) );
10986 return;
10987 }
10988
10989 // First, see if we hit a monster
10990 if( monster *const critter = g->critter_at<monster>( to ) ) {
10991 deal_damage( critter, bodypart_id( "torso" ), damage_instance( DT_BASH, critter->type->size ) );
10992 add_effect( effect_stunned, 1_turns );
10993 /** @EFFECT_STR_MAX allows knocked back player to knock back, damage, stun some monsters */
10994 if( ( str_max - 6 ) / 4 > critter->type->size ) {
10995 critter->knock_back_from( pos() ); // Chain reaction!
10996 critter->apply_damage( this, bodypart_id( "torso" ), ( str_max - 6 ) / 4 );
10997 critter->add_effect( effect_stunned, 1_turns );
10998 } else if( ( str_max - 6 ) / 4 == critter->type->size ) {
10999 critter->apply_damage( this, bodypart_id( "torso" ), ( str_max - 6 ) / 4 );
11000 critter->add_effect( effect_stunned, 1_turns );
11001 }
11002 critter->check_dead_state();
11003
11004 add_msg_player_or_npc( _( "You bounce off a %s!" ), _( "<npcname> bounces off a %s!" ),
11005 critter->name() );
11006 return;
11007 }
11008
11009 if( npc *const np = g->critter_at<npc>( to ) ) {
11010 deal_damage( np, bodypart_id( "torso" ), damage_instance( DT_BASH, np->get_size() + 1 ) );
11011 add_effect( effect_stunned, 1_turns );
11012 np->deal_damage( this, bodypart_id( "torso" ), damage_instance( DT_BASH, 3 ) );
11013 add_msg_player_or_npc( _( "You bounce off %s!" ), _( "<npcname> bounces off %s!" ),
11014 np->name );
11015 np->check_dead_state();
11016 return;
11017 }
11018
11019 // If we're still in the function at this point, we're actually moving a tile!
11020 if( g->m.has_flag( "LIQUID", to ) && g->m.has_flag( TFLAG_DEEP_WATER, to ) ) {
11021 if( !is_npc() ) {
11022 avatar_action::swim( g->m, g->u, to );
11023 }
11024 // TODO: NPCs can't swim!
11025 } else if( g->m.impassable( to ) ) { // Wait, it's a wall
11026
11027 // It's some kind of wall.
11028 // TODO: who knocked us back? Maybe that creature should be the source of the damage?
11029 apply_damage( nullptr, bodypart_id( "torso" ), 3 );
11030 add_effect( effect_stunned, 2_turns );
11031 add_msg_player_or_npc( _( "You bounce off a %s!" ), _( "<npcname> bounces off a %s!" ),
11032 g->m.obstacle_name( to ) );
11033
11034 } else { // It's no wall
11035 setpos( to );
11036
11037 map &here = get_map();
11038 here.creature_on_trap( *this );
11039 }
11040}
void creature_on_trap(Creature &critter, bool may_avoid=true)
Apply trap effects to the creature, similar to creature_in_field.
Definition: map.cpp:8628
@ TFLAG_DEEP_WATER
Definition: mapdata.h:301
void swim(map &m, avatar &you, const tripoint &p)
Handles swimming by the player.

References _, Creature::add_effect(), Creature::add_msg_player_or_npc(), apply_damage(), map::creature_on_trap(), deal_damage(), DT_BASH, effect_stunned, g, get_map(), Creature::is_npc(), one_in(), pos(), rl_dist(), setpos(), str_max, avatar_action::swim(), TFLAG_DEEP_WATER, tripoint::x, and tripoint::y.

◆ knows_recipe()

bool Character::knows_recipe ( const recipe rec) const

Definition at line 10596 of file character.cpp.

10597{
10598 return get_learned_recipes().contains( *rec );
10599}
const recipe_subset & get_learned_recipes() const
Returns all known recipes.
bool contains(const recipe &r) const
Check if the subset contains a recipe with the specified id.

References recipe_subset::contains(), and get_learned_recipes().

Referenced by item::book_info(), complete_craft(), crafting::complete_disassemble(), avatar::create(), avatar::do_read(), find_repair_difficulty(), read_inventory_preset::get_known_recipes(), player::has_recipe(), select_crafting_recipe(), conditional_t< T >::set_u_know_recipe(), and skim_book_msg().

◆ knows_trap()

bool Character::knows_trap ( const tripoint pos) const

Definition at line 10248 of file character.cpp.

10249{
10250 const tripoint p = get_map().getabs( pos );
10251 return known_traps.count( p ) > 0;
10252}

References get_map(), map::getabs(), known_traps, and pos().

Referenced by trap::can_see(), vehicle::handle_trap(), and character_funcs::search_surroundings().

◆ leak_level()

int Character::leak_level ( const std::string &  flag) const

Definition at line 2037 of file suffer.cpp.

2038{
2039 int leak_level = 0;
2040 leak_level = inv.leak_level( flag );
2041 return leak_level;
2042}
int leak_level(const std::string &flag) const
Definition: suffer.cpp:2037
int leak_level(const std::string &flag) const
Definition: inventory.cpp:899

References inv, leak_level(), and inventory::leak_level().

Referenced by iexamine::autodoc(), iuse::geiger(), leak_level(), and suffer_from_radiation().

◆ learn_recipe()

void Character::learn_recipe ( const recipe rec)

Definition at line 10601 of file character.cpp.

10602{
10603 if( rec->never_learn ) {
10604 return;
10605 }
10606 learned_recipes->include( rec );
10607}
bool never_learn
Prevent this recipe from ever being added to the player's learned recipies ( used for special NPC cra...
Definition: recipe.h:93

References learned_recipes, and recipe::never_learn.

Referenced by debug_menu::character_edit_menu(), complete_craft(), crafting::complete_disassemble(), avatar::create(), and avatar::do_read().

◆ limb_color()

nc_color Character::limb_color ( const bodypart_id bp,
bool  bleed,
bool  bite,
bool  infect 
) const

Definition at line 5959 of file character.cpp.

5960{
5961 if( bp == bodypart_id( "num_bp" ) ) {
5962 return c_light_gray;
5963 }
5964 const body_part bp_token = bp->token;
5965 int color_bit = 0;
5966 nc_color i_color = c_light_gray;
5967 if( bleed && has_effect( effect_bleed, bp_token ) ) {
5968 color_bit += 1;
5969 }
5970 if( bite && has_effect( effect_bite, bp_token ) ) {
5971 color_bit += 10;
5972 }
5973 if( infect && has_effect( effect_infected, bp_token ) ) {
5974 color_bit += 100;
5975 }
5976 switch( color_bit ) {
5977 case 1:
5978 i_color = c_red;
5979 break;
5980 case 10:
5981 i_color = c_blue;
5982 break;
5983 case 100:
5984 i_color = c_green;
5985 break;
5986 case 11:
5987 i_color = c_magenta;
5988 break;
5989 case 101:
5990 i_color = c_yellow;
5991 break;
5992 }
5993
5994 return i_color;
5995}

References Creature::bleed(), c_blue, c_green, c_light_gray, c_magenta, c_red, c_yellow, effect_bite, effect_bleed, effect_infected, and Creature::has_effect().

Referenced by body_window(), draw_health_classic(), draw_limb2(), draw_limb_narrow(), draw_limb_wide(), and extended_description().

◆ load()

void Character::load ( const JsonObject data)
protected

Gather variables for saving.

These variables are common to both the avatar and NPCs.

Definition at line 387 of file savegame_json.cpp.

388{
390 Creature::load( data );
391
392 if( !data.read( "posx", position.x ) ) { // uh-oh.
393 debugmsg( "BAD PLAYER/NPC JSON: no 'posx'?" );
394 }
395 data.read( "posy", position.y );
396 if( !data.read( "posz", position.z ) && g != nullptr ) {
397 position.z = g->get_levz();
398 }
399 // stats
400 data.read( "str_cur", str_cur );
401 data.read( "str_max", str_max );
402 data.read( "dex_cur", dex_cur );
403 data.read( "dex_max", dex_max );
404 data.read( "int_cur", int_cur );
405 data.read( "int_max", int_max );
406 data.read( "per_cur", per_cur );
407 data.read( "per_max", per_max );
408
409 data.read( "str_bonus", str_bonus );
410 data.read( "dex_bonus", dex_bonus );
411 data.read( "per_bonus", per_bonus );
412 data.read( "int_bonus", int_bonus );
413 data.read( "omt_path", omt_path );
414
415 std::string new_name;
416 data.read( "name", new_name );
417 if( !new_name.empty() ) {
418 // Bugfix for name not having been saved properly
419 name = new_name;
420 }
421
422 data.read( "base_age", init_age );
423 data.read( "base_height", init_height );
424
425 if( !data.read( "profession", prof ) || !prof.is_valid() ) {
426 // We are likely an older profession which has since been removed so just set to default.
427 // This is only cosmetic after game start.
429 }
430 data.read( "custom_profession", custom_profession );
431
432 // needs
433 data.read( "thirst", thirst );
434 data.read( "fatigue", fatigue );
435 data.read( "sleep_deprivation", sleep_deprivation );
436 data.read( "stored_calories", stored_calories );
437 data.read( "radiation", radiation );
438 data.read( "oxygen", oxygen );
439 data.read( "pkill", pkill );
440
441 data.read( "type_of_scent", type_of_scent );
442
443 if( data.has_array( "ma_styles" ) ) {
444 std::vector<matype_id> temp_styles;
445 data.read( "ma_styles", temp_styles );
446 bool temp_keep_hands_free = false;
447 data.read( "keep_hands_free", temp_keep_hands_free );
448 matype_id temp_selected_style;
449 data.read( "style_selected", temp_selected_style );
450 if( !temp_selected_style.is_valid() ) {
451 temp_selected_style = matype_id( "style_none" );
452 }
454 temp_styles, temp_selected_style, temp_keep_hands_free
455 ) );
456 } else {
457 data.read( "martial_arts_data", martial_arts_data );
458 }
459
460 JsonObject vits = data.get_object( "vitamin_levels" );
462 for( const std::pair<const vitamin_id, vitamin> &v : vitamin::all() ) {
463 if( vits.has_member( v.first.str() ) ) {
464 int lvl = vits.get_int( v.first.str() );
465 vitamin_levels[v.first] = clamp( lvl, v.first->min(), v.first->max() );
466 }
467 }
468 data.read( "consumption_history", consumption_history );
469 data.read( "activity", activity );
470 data.read( "destination_activity", destination_activity );
471 data.read( "stashed_outbounds_activity", stashed_outbounds_activity );
472 data.read( "stashed_outbounds_backlog", stashed_outbounds_backlog );
473 data.read( "backlog", backlog );
474 if( !backlog.empty() && !backlog.front().str_values.empty() && ( ( activity &&
475 activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) || ( destination_activity &&
476 destination_activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) ) ) {
477 requirement_data fetch_reqs;
478 data.read( "fetch_data", fetch_reqs );
479 const requirement_id req_id( backlog.front().str_values.back() );
480 requirement_data::save_requirement( fetch_reqs, req_id );
481 }
482 // npc activity on vehicles.
483 data.read( "activity_vehicle_part_index", activity_vehicle_part_index );
484 // health
485 data.read( "healthy", healthy );
486 data.read( "healthy_mod", healthy_mod );
487 data.read( "healed_24h", healed_total );
488
489 // status
490 temp_cur.fill( 5000 );
491 data.read( "temp_cur", temp_cur );
492
493 temp_conv.fill( 5000 );
494 data.read( "temp_conv", temp_conv );
495
496 frostbite_timer.fill( 0 );
497 data.read( "frostbite_timer", frostbite_timer );
498
499 body_wetness.fill( 0 );
500 data.read( "body_wetness", body_wetness );
501
502 //energy
503 data.read( "stim", stim );
504 data.read( "stamina", stamina );
505
506 data.read( "damage_bandaged", damage_bandaged );
507 data.read( "damage_disinfected", damage_disinfected );
508 data.read( "magic", magic );
509 JsonArray parray;
510
511 data.read( "traits", my_traits );
512 for( auto it = my_traits.begin(); it != my_traits.end(); ) {
513 const auto &tid = *it;
514 if( tid.is_valid() ) {
515 ++it;
516 } else {
517 debugmsg( "character %s has invalid trait %s, it will be ignored", name, tid.c_str() );
518 my_traits.erase( it++ );
519 }
520 }
521
522 data.read( "mutations", my_mutations );
523 for( auto it = my_mutations.begin(); it != my_mutations.end(); ) {
524 const trait_id &mid = it->first;
525 if( mid.is_valid() ) {
526 on_mutation_gain( mid );
527 cached_mutations.push_back( &mid.obj() );
528 ++it;
529 } else {
530 debugmsg( "character %s has invalid mutation %s, it will be ignored", name, mid.c_str() );
531 it = my_mutations.erase( it );
532 }
533 }
535
536 data.read( "my_bionics", *my_bionics );
537
538 for( auto &w : worn ) {
539 w.on_takeoff( *this );
540 }
541 worn.clear();
542 data.read( "worn", worn );
543 for( auto &w : worn ) {
544 on_item_wear( w );
545 }
546
547 if( data.has_array( "hp_cur" ) ) {
548 set_anatomy( anatomy_id( "human_anatomy" ) );
549 set_body();
550 std::array<int, 6> hp_cur;
551 data.read( "hp_cur", hp_cur );
552 std::array<int, 6> hp_max;
553 data.read( "hp_max", hp_max );
554 set_part_hp_max( bodypart_id( "head" ), hp_max[0] );
555 set_part_hp_cur( bodypart_id( "head" ), hp_cur[0] );
556
557 set_part_hp_max( bodypart_id( "torso" ), hp_max[1] );
558 set_part_hp_cur( bodypart_id( "torso" ), hp_cur[1] );
559
560 set_part_hp_max( bodypart_id( "arm_l" ), hp_max[2] );
561 set_part_hp_cur( bodypart_id( "arm_l" ), hp_cur[2] );
562
563 set_part_hp_max( bodypart_id( "arm_r" ), hp_max[3] );
564 set_part_hp_cur( bodypart_id( "arm_r" ), hp_cur[3] );
565
566 set_part_hp_max( bodypart_id( "leg_l" ), hp_max[4] );
567 set_part_hp_cur( bodypart_id( "leg_l" ), hp_cur[4] );
568
569 set_part_hp_max( bodypart_id( "leg_r" ), hp_max[5] );
570 set_part_hp_cur( bodypart_id( "leg_r" ), hp_cur[5] );
571 }
572
573
574 inv.clear();
575 if( data.has_member( "inv" ) ) {
576 JsonIn *invin = data.get_raw( "inv" );
577 inv.json_load_items( *invin );
578 }
579
581 data.read( "weapon", primary_weapon() );
582
583 data.read( "move_mode", move_mode );
584
585 if( has_effect( effect_riding ) ) {
586 int temp_id;
587 if( data.read( "mounted_creature", temp_id ) ) {
588 mounted_creature_id = temp_id;
589 mounted_creature = g->critter_tracker->from_temporary_id( temp_id );
590 } else {
591 mounted_creature = nullptr;
592 }
593 }
594
595 morale->load( data );
596 // Have to go through effects again, in case an effect gained a morale bonus
597 for( const auto &elem : *effects ) {
598 for( const std::pair<const bodypart_str_id, effect> &_effect_it : elem.second ) {
599 const effect &e = _effect_it.second;
601 }
602 }
603
604 _skills->clear();
605 for( const JsonMember member : data.get_object( "skills" ) ) {
606 member.read( ( *_skills )[skill_id( member.name() )] );
607 }
608
609 data.read( "learned_recipes", *learned_recipes );
610 autolearn_skills_stamp->clear(); // Invalidates the cache
611
612 on_stat_change( "thirst", thirst );
613 on_stat_change( "stored_calories", stored_calories );
614 on_stat_change( "fatigue", fatigue );
615 on_stat_change( "sleep_deprivation", sleep_deprivation );
616 on_stat_change( "pkill", pkill );
617 on_stat_change( "perceived_pain", get_perceived_pain() );
620
621 assign( data, "power_level", power_level, false, 0_kJ );
622 assign( data, "max_power_level", max_power_level, false, 0_kJ );
623
624 // Bionic power should not be negative!
625 if( power_level < 0_J ) {
626 power_level = 0_J;
627 }
628
629 JsonArray overmap_time_array = data.get_array( "overmap_time" );
630 overmap_time.clear();
631 while( overmap_time_array.has_more() ) {
632 point_abs_omt pt;
633 overmap_time_array.read_next( pt );
634 time_duration tdr = 0_turns;
635 overmap_time_array.read_next( tdr );
636 overmap_time[pt] = tdr;
637 }
638 data.read( "stomach", stomach );
639 data.read( "automoveroute", auto_move_route );
640
641 known_traps.clear();
642 for( JsonObject pmap : data.get_array( "known_traps" ) ) {
643 pmap.allow_omitted_members();
644 const tripoint p( pmap.get_int( "x" ), pmap.get_int( "y" ), pmap.get_int( "z" ) );
645 const std::string t = pmap.get_string( "trap" );
646 known_traps.insert( trap_map::value_type( p, t ) );
647 }
648}
bool assign(const JsonObject &jo, const std::string &name, bool &val, bool strict)
Definition: assign.cpp:16
void on_stat_change(const std::string &stat, int value) override
Called when a stat is changed.
Definition: character.cpp:9911
std::map< vitamin_id, int > vitamin_levels
Current deficiency/excess quantity for each vitamin.
Definition: character.h:2208
int activity_vehicle_part_index
Definition: character.h:1621
void on_effect_int_change(const efftype_id &effect_type, int intensity, const bodypart_str_id &bp) override
Called when effect intensity has been changed.
Definition: character.cpp:9882
int oxygen
Definition: character.h:1593
void on_item_wear(const item &it)
Called when an item is worn.
Definition: character.cpp:9854
void recalculate_size()
Recalculate size class of character.
Definition: mutation.cpp:244
int mounted_creature_id
Definition: character.h:1619
void set_part_hp_max(const bodypart_id &id, int set)
Definition: creature.cpp:1626
void load(const JsonObject &jsin)
bool has_more() const
Definition: json.cpp:552
bool read_next(T &t)
Definition: json.h:1112
Definition: json.h:172
Represents a member of a JsonObject.
Definition: json.h:1249
JsonObject get_object(const std::string &name) const
Definition: json.cpp:429
JsonArray get_array(const std::string &name) const
Definition: json.cpp:400
bool has_member(const std::string &name) const
Definition: json.cpp:182
JsonIn * get_raw(const std::string &name) const
Definition: json.cpp:309
int get_int(const std::string &name) const
Definition: json.cpp:350
bool has_array(const std::string &name) const
Definition: json.cpp:483
void allow_omitted_members() const
Definition: json.cpp:151
bool read(const std::string &name, T &t, bool throw_on_error=true) const
Definition: json.h:941
void json_load_items(JsonIn &jsin)
void clear()
Definition: inventory.cpp:238
This is a wrapper for implementing the pointer-to-implementation technique, see for example http://en...
Definition: pimpl.h:35
const char * c_str() const
Interface to the plain C-string of the id.
Definition: string_id.h:247
static const std::map< vitamin_id, vitamin > & all()
Get all currently loaded vitamins.
Definition: vitamin.cpp:98
std::string member
Definition: mapgen.cpp:410
static const efftype_id effect_riding("riding")
static void save_requirement(const requirement_data &req, const requirement_id &id=requirement_id::NULL_ID())
Store requirement data for future lookup.

References _skills, activity, activity_vehicle_part_index, vitamin::all(), JsonObject::allow_omitted_members(), assign(), auto_move_route, autolearn_skills_stamp, backlog, body_wetness, string_id< T >::c_str(), cached_mutations, clamp(), inventory::clear(), consumption_history, custom_profession, damage_bandaged, damage_disinfected, debugmsg, destination_activity, dex_bonus, dex_cur, dex_max, effect_riding, Creature::effects, fatigue, frostbite_timer, g, profession::generic(), JsonObject::get_array(), effect::get_bp(), effect::get_id(), JsonObject::get_int(), effect::get_intensity(), JsonObject::get_object(), get_perceived_pain(), JsonObject::get_raw(), JsonObject::has_array(), Creature::has_effect(), JsonObject::has_member(), JsonArray::has_more(), healed_total, healthy, healthy_mod, player_activity::id(), init_age, init_height, int_bonus, int_cur, int_max, inv, string_id< T >::is_valid(), inventory::json_load_items(), known_traps, learned_recipes, Creature::load(), magic, martial_arts_data, matype_id, max_power_level, mapgen_defer::member, morale, mounted_creature, mounted_creature_id, move_mode, my_bionics, my_mutations, my_traits, name, string_id< T >::obj(), omt_path, on_effect_int_change(), on_item_wear(), on_mutation_gain(), on_stat_change(), overmap_time, oxygen, per_bonus, per_cur, per_max, pkill, position, power_level, primary_weapon(), prof, radiation, JsonObject::read(), JsonArray::read_next(), recalc_sight_limits(), recalculate_size(), reset_encumbrance(), requirement_data::save_requirement(), Creature::set_anatomy(), Creature::set_body(), Creature::set_part_hp_cur(), Creature::set_part_hp_max(), set_primary_weapon(), skill_id, sleep_deprivation, stamina, calendar::start_of_cataclysm, stashed_outbounds_activity, stashed_outbounds_backlog, stim, stomach, stored_calories, str_bonus, str_cur, str_max, temp_conv, temp_cur, thirst, type_of_scent, vitamin_levels, worn, tripoint::x, tripoint::y, and tripoint::z.

Referenced by player::load().

◆ mabuff_armor_bonus()

int Character::mabuff_armor_bonus ( damage_type  type) const

Returns the armor bonus against given type from martial arts buffs.

Definition at line 1170 of file martialarts.cpp.

1171{
1172 int ret = 0;
1173 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1174 ret += d.get_intensity() * b.armor_bonus( *this, type );
1175 } );
1176 return ret;
1177}
static void accumulate_ma_buff_effects(const C &container, F f)

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by passive_absorb_hit().

◆ mabuff_arpen_bonus()

int Character::mabuff_arpen_bonus ( damage_type  type) const

Returns the arpen bonus from martial arts buffs.

Definition at line 1162 of file martialarts.cpp.

1163{
1164 int ret = 0;
1165 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1166 ret += d.get_intensity() * b.arpen_bonus( *this, type );
1167 } );
1168 return ret;
1169}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ mabuff_attack_cost_mult()

float Character::mabuff_attack_cost_mult ( ) const

Returns the multiplier on move cost of attacks.

Definition at line 1204 of file martialarts.cpp.

1205{
1206 float ret = 1.0f;
1207 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1208 // This is correct, so that a 20% buff (1.2) plus a 20% buff (1.2)
1209 // becomes 1.4 instead of 2.4 (which would be a 240% buff)
1210 ret *= d.get_intensity() * ( b.bonuses.get_mult( *this,
1211 affected_stat::MOVE_COST ) - 1 ) + 1;
1212 } );
1213 return ret;
1214}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), MOVE_COST, and cata::hash64_detail::ret.

Referenced by attack_cost().

◆ mabuff_attack_cost_penalty()

int Character::mabuff_attack_cost_penalty ( ) const

Returns the flat penalty to move cost of attacks.

If negative, that's a bonus. Applied after multiplier.

Definition at line 1196 of file martialarts.cpp.

1197{
1198 int ret = 0;
1199 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1200 ret += d.get_intensity() * b.bonuses.get_flat( *this, affected_stat::MOVE_COST );
1201 } );
1202 return ret;
1203}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), MOVE_COST, and cata::hash64_detail::ret.

Referenced by attack_cost().

◆ mabuff_block_bonus()

int Character::mabuff_block_bonus ( ) const

Returns the block bonus from martial arts buffs.

Definition at line 1146 of file martialarts.cpp.

1147{
1148 int ret = 0;
1149 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1150 ret += d.get_intensity() * b.block_bonus( *this );
1151 } );
1152 return ret;
1153}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), and cata::hash64_detail::ret.

Referenced by block_hit().

◆ mabuff_damage_bonus()

int Character::mabuff_damage_bonus ( damage_type  type) const

Returns the flat damage bonus to given type from martial arts buffs, applied after the multiplier.

Definition at line 1188 of file martialarts.cpp.

1189{
1190 int ret = 0;
1191 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1192 ret += d.get_intensity() * b.damage_bonus( *this, type );
1193 } );
1194 return ret;
1195}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ mabuff_damage_mult()

float Character::mabuff_damage_mult ( damage_type  type) const

Returns the damage multiplier to given type from martial arts buffs.

Definition at line 1178 of file martialarts.cpp.

1179{
1180 float ret = 1.f;
1181 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1182 // This is correct, so that a 20% buff (1.2) plus a 20% buff (1.2)
1183 // becomes 1.4 instead of 2.4 (which would be a 240% buff)
1184 ret *= d.get_intensity() * ( b.damage_mult( *this, type ) - 1 ) + 1;
1185 } );
1186 return ret;
1187}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ mabuff_dodge_bonus()

float Character::mabuff_dodge_bonus ( ) const

Returns the dodge bonus from martial arts buffs.

Definition at line 1138 of file martialarts.cpp.

1139{
1140 float ret = 0;
1141 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1142 ret += d.get_intensity() * b.dodge_bonus( *this );
1143 } );
1144 return ret;
1145}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), and cata::hash64_detail::ret.

Referenced by reset_stats().

◆ mabuff_speed_bonus()

int Character::mabuff_speed_bonus ( ) const

Returns the speed bonus from martial arts buffs.

Definition at line 1154 of file martialarts.cpp.

1155{
1156 int ret = 0;
1157 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1158 ret += d.get_intensity() * b.speed_bonus( *this );
1159 } );
1160 return ret;
1161}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), and cata::hash64_detail::ret.

Referenced by recalc_speed_bonus().

◆ mabuff_tohit_bonus()

float Character::mabuff_tohit_bonus ( ) const

Returns the to hit bonus from martial arts buffs.

Definition at line 1130 of file martialarts.cpp.

1131{
1132 float ret = 0;
1133 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & ) {
1134 ret += b.hit_bonus( *this );
1135 } );
1136 return ret;
1137}

References accumulate_ma_buff_effects(), b, Creature::effects, and cata::hash64_detail::ret.

Referenced by get_melee_hit_base().

◆ made_of()

bool Character::made_of ( const material_id m) const
overridevirtual

Implements Creature.

Definition at line 6245 of file character.cpp.

6246{
6247 // TODO: check for mutations that change this.
6248 return std::find( fleshy.begin(), fleshy.end(), m ) != fleshy.end();
6249}
static const std::vector< material_id > fleshy
Definition: character.h:786

References detail::find(), and fleshy.

Referenced by block_hit().

◆ made_of_any()

bool Character::made_of_any ( const std::set< material_id > &  ms) const
overridevirtual

Implements Creature.

Definition at line 6250 of file character.cpp.

6251{
6252 // TODO: check for mutations that change this.
6253 return std::any_of( fleshy.begin(), fleshy.end(), [&ms]( const material_id & e ) {
6254 return ms.count( e );
6255 } );
6256}
constexpr scale ms
Definition: coordinates.h:30

References fleshy, and coords::ms.

◆ max_stored_kcal()

◆ meets_requirements()

bool Character::meets_requirements ( const item it,
const item context = item() 
) const

Checks whether the character meets overall requirements to be able to use the item.

Definition at line 3542 of file character.cpp.

3543{
3544 const auto &ctx = !context.is_null() ? context : it;
3546}
bool meets_stat_requirements(const item &it) const
Checks whether the character's stats meets the stats required by the item.
Definition: character.cpp:3534

References item::is_null(), meets_skill_requirements(), meets_stat_requirements(), itype::min_skills, and item::type.

Referenced by can_use(), gunmod_inventory_preset::get_denial(), and item::gun_range().

◆ meets_skill_requirements() [1/2]

bool Character::meets_skill_requirements ( const construction con) const

Checks whether the character's skills meet the required.

Definition at line 3526 of file character.cpp.

3527{
3528 return std::all_of( con.required_skills.begin(), con.required_skills.end(),
3529 [&]( const std::pair<skill_id, int> &pr ) {
3530 return get_skill_level( pr.first ) >= pr.second;
3531 } );
3532}
std::map< skill_id, int > required_skills
Skill->skill level mapping.
Definition: construction.h:72

References construction::required_skills.

◆ meets_skill_requirements() [2/2]

bool Character::meets_skill_requirements ( const std::map< skill_id, int > &  req,
const item context = item() 
) const

Checks whether the character's skills meet the required.

Definition at line 3520 of file character.cpp.

3522{
3523 return _skills->meets_skill_requirements( req, context );
3524}

References _skills.

Referenced by activity_handlers::build_do_turn(), can_learn_by_disassembly(), find_base_construction(), get_learned_recipes(), meets_requirements(), and player_can_build().

◆ meets_stat_requirements()

bool Character::meets_stat_requirements ( const item it) const

Checks whether the character's stats meets the stats required by the item.

Definition at line 3534 of file character.cpp.

3535{
3536 return ( it.has_flag( flag_STR_DRAW ) || get_str() >= it.get_min_str() ) &&
3537 get_dex() >= it.type->min_dex &&
3538 get_int() >= it.type->min_int &&
3539 get_per() >= it.type->min_per;
3540}
static const std::string flag_STR_DRAW("STR_DRAW")

References flag_STR_DRAW(), get_dex(), get_int(), item::get_min_str(), get_per(), get_str(), item::has_flag(), itype::min_dex, itype::min_int, itype::min_per, and item::type.

Referenced by meets_requirements().

◆ melee_attack()

void Character::melee_attack ( Creature t,
bool  allow_special,
const matec_id force_technique = nullptr,
bool  allow_unarmed = true 
)

Sets up a melee attack and handles melee attack function calls.

Parameters
tCreature to attack
allow_specialwhether non-forced martial art technique or mutation attack should be possible with this attack.
force_techniquespecial technique to use in attack (leave as nullptr to use random technique).
allow_unarmedalways uses the wielded weapon regardless of martialarts style
Melee reduces stamina cost of melee attacks

Definition at line 444 of file melee.cpp.

446{
448 int hit_spread = t.deal_melee_attack( this, hit_roll() );
449 if( !t.is_player() ) {
450 // TODO: Per-NPC tracking? Right now monster hit by either npc or player will draw aggro...
451 t.add_effect( effect_hit_by_player, 10_minutes ); // Flag as attacked by us for AI
452 }
453 if( is_mounted() ) {
454 auto mons = mounted_creature.get();
455 if( mons->has_flag( MF_RIDEABLE_MECH ) ) {
456 if( !mons->check_mech_powered() ) {
457 add_msg( m_bad, _( "The %s has dead batteries and will not move its arms." ),
458 mons->get_name() );
459 return;
460 }
461 if( mons->type->has_special_attack( "SMASH" ) && one_in( 3 ) ) {
462 add_msg( m_info, _( "The %s hisses as its hydraulic arm pumps forward!" ),
463 mons->get_name() );
464 mattack::smash_specific( mons, &t );
465 } else {
466 mons->use_mech_power( -2 );
467 mons->melee_attack( t );
468 }
469 mod_moves( -mons->type->attack_cost );
470 return;
471 }
472 }
473 item &cur_weapon = allow_unarmed ? used_weapon() : primary_weapon();
474
475 if( cur_weapon.attack_cost() > attack_cost( cur_weapon ) * 20 ) {
476 add_msg( m_bad, _( "This weapon is too unwieldy to attack with!" ) );
477 return;
478 }
479
480 int move_cost = attack_cost( cur_weapon );
481
482 if( hit_spread < 0 ) {
483 int stumble_pen = stumble( *this, cur_weapon );
484 sfx::generate_melee_sound( pos(), t.pos(), false, false );
485 if( is_player() ) { // Only display messages if this is the player
486
487 if( one_in( 2 ) ) {
488 const std::string reason_for_miss = get_miss_reason();
489 if( !reason_for_miss.empty() ) {
490 add_msg( reason_for_miss );
491 }
492 }
493
494 if( can_miss_recovery( cur_weapon ) ) {
495 ma_technique tec = martial_arts_data->get_miss_recovery_tec( cur_weapon );
496 add_msg( _( tec.avatar_message ), t.disp_name() );
497 } else if( stumble_pen >= 60 ) {
498 add_msg( m_bad, _( "You miss and stumble with the momentum." ) );
499 } else if( stumble_pen >= 10 ) {
500 add_msg( _( "You swing wildly and miss." ) );
501 } else {
502 add_msg( _( "You miss." ) );
503 }
504 } else if( g->u.sees( *this ) ) {
505 if( stumble_pen >= 60 ) {
506 add_msg( _( "%s misses and stumbles with the momentum." ), name );
507 } else if( stumble_pen >= 10 ) {
508 add_msg( _( "%s swings wildly and misses." ), name );
509 } else {
510 add_msg( _( "%s misses." ), name );
511 }
512 }
513
514 // Practice melee and relevant weapon skill (if any) except when using CQB bionic
515 if( !has_active_bionic( bio_cqb ) ) {
516 melee_train( *this, 2, 5, cur_weapon );
517 }
518
519 // Cap stumble penalty, heavy weapons are quite weak already
520 move_cost += std::min( 60, stumble_pen );
521 if( martial_arts_data->has_miss_recovery_tec( cur_weapon ) ) {
522 move_cost /= 2;
523 }
524
525 // trigger martial arts on-miss effects
526 martial_arts_data->ma_onmiss_effects( *this );
527 } else {
529 // Remember if we see the monster at start - it may change
530 const bool seen = g->u.sees( t );
531 // Start of attacks.
532 const bool critical_hit = scored_crit( t.dodge_roll(), cur_weapon );
533 if( critical_hit ) {
535 }
537 roll_all_damage( critical_hit, d, false, cur_weapon );
538
539 const bool has_force_technique = force_technique;
540
541 // Pick one or more special attacks
542 matec_id technique_id;
543 if( allow_special && !has_force_technique ) {
544 technique_id = pick_technique( t, cur_weapon, critical_hit, false, false );
545 } else if( has_force_technique ) {
546 technique_id = *force_technique;
547 } else {
548 technique_id = tec_none;
549 }
550
551 // if you have two broken arms you aren't doing any martial arts
552 // and your hits are not going to hurt very much
553 if( get_working_arm_count() < 1 ) {
554 technique_id = tec_none;
555 d.mult_damage( 0.1 );
556 }
557 // polearms and pikes (but not spears) do less damage to adjacent targets
558 if( cur_weapon.reach_range( *this ) > 1 && !reach_attacking &&
559 cur_weapon.has_flag( "POLEARM" ) ) {
560 d.mult_damage( 0.7 );
561 }
562
563 const ma_technique &technique = technique_id.obj();
564
565 // Handles effects as well; not done in melee_affect_*
566 if( technique.id != tec_none ) {
567 perform_technique( technique, t, d, move_cost );
568 }
569
570 // Proceed with melee attack.
571 if( !t.is_dead_state() ) {
572 // Handles speed penalties to monster & us, etc
573 std::string specialmsg = melee_special_effects( t, d, cur_weapon );
574
575 // gets overwritten with the dealt damage values
576 dealt_damage_instance dealt_dam;
577 dealt_damage_instance dealt_special_dam;
578 if( allow_special ) {
579 perform_special_attacks( t, dealt_special_dam );
580 }
581 t.deal_melee_hit( this, hit_spread, critical_hit, d, dealt_dam );
582 if( dealt_special_dam.type_damage( DT_CUT ) > 0 ||
583 dealt_special_dam.type_damage( DT_STAB ) > 0 ||
584 ( cur_weapon.is_null() && ( dealt_dam.type_damage( DT_CUT ) > 0 ||
585 dealt_dam.type_damage( DT_STAB ) > 0 ) ) ) {
586 if( has_trait( trait_POISONOUS ) ) {
587 add_msg_if_player( m_good, _( "You poison %s!" ), t.disp_name() );
588 t.add_effect( effect_poison, 6_turns );
589 } else if( has_trait( trait_POISONOUS2 ) ) {
590 add_msg_if_player( m_good, _( "You inject your venom into %s!" ),
591 t.disp_name() );
592 t.add_effect( effect_badpoison, 6_turns );
593 }
594 }
595
596 // Make a rather quiet sound, to alert any nearby monsters
597 if( !is_quiet() ) { // check martial arts silence
598 //sound generated later
599 sounds::sound( pos(), 8, sounds::sound_t::combat, "whack!" );
600 }
601 std::string material = "flesh";
602 if( t.is_monster() ) {
603 const monster *m = dynamic_cast<const monster *>( &t );
604 if( m->made_of( material_id( "steel" ) ) ) {
605 material = "steel";
606 }
607 }
608 sfx::generate_melee_sound( pos(), t.pos(), true, t.is_monster(), material );
609 int dam = dealt_dam.total_damage();
611
612 // Practice melee and relevant weapon skill (if any) except when using CQB bionic
613 if( !has_active_bionic( bio_cqb ) ) {
614 melee_train( *this, 5, 10, cur_weapon );
615 }
616
617 if( dam >= 5 && has_artifact_with( AEP_SAP_LIFE ) ) {
618 healall( rng( dam / 10, dam / 5 ) );
619 }
620
621 // Treat monster as seen if we see it before or after the attack
622 if( seen || g->u.sees( t ) ) {
623 std::string message = melee_message( technique, *this, dealt_dam );
624 player_hit_message( this, message, t, dam, critical_hit );
625 } else {
626 add_msg_player_or_npc( m_good, _( "You hit something." ),
627 _( "<npcname> hits something." ) );
628 }
629
630 if( !specialmsg.empty() ) {
631 add_msg_if_player( m_neutral, specialmsg );
632 }
633
634 if( critical_hit ) {
635 // trigger martial arts on-crit effects
636 martial_arts_data->ma_oncrit_effects( *this );
637 }
638
639 }
640
642 did_hit( t );
643
644 if( t.is_dead_state() ) {
645 // trigger martial arts on-kill effects
646 martial_arts_data->ma_onkill_effects( *this );
647 }
648 }
649
650 const int melee = get_skill_level( skill_melee );
651
652 // Previously calculated as 2_gram * std::max( 1, str_cur )
653 // using 16_gram normalizes it to 8 str. Same effort expenditure
654 // for each strike, regardless of weight. This is compensated
655 // for by the additional move cost as weapon weight increases
656 const int weight_cost = cur_weapon.weight() / ( 16_gram );
657 const int encumbrance_cost = roll_remainder( ( encumb( bp_arm_l ) + encumb( bp_arm_r ) ) *
658 2.0f );
659 const int deft_bonus = hit_spread < 0 && has_trait( trait_DEFT ) ? 50 : 0;
660 const float skill_cost = std::max( 0.667f, static_cast<float>( ( 30.0f - melee ) / 30.0f ) );
661 /** @EFFECT_MELEE reduces stamina cost of melee attacks */
662 const int mod_sta = ( weight_cost + encumbrance_cost - deft_bonus + 50 ) * -1 * skill_cost;
663 mod_stamina( std::min( -50, mod_sta ) );
664 add_msg( m_debug, "Stamina burn: %d", std::min( -50, mod_sta ) );
666 // trigger martial arts on-attack effects
667 martial_arts_data->ma_onattack_effects( *this );
668 // some things (shattering weapons) can harm the attacking creature.
670 if( t.as_character() ) {
672 t.as_character()->on_hit( this, bodypart_id( "num_bp" ), &dp );
673 }
674 return;
675}
int attack_cost(const item &weap) const
Returns cost (in moves) of attacking with given item (no modifiers, like stuck)
Definition: melee.cpp:2279
bool can_miss_recovery(const item &weap) const
Returns true if the player is able to use a miss recovery technique.
std::string melee_special_effects(Creature &t, damage_instance &d, item &weap)
Handles combat effects, returns a string of any valid combat effect messages.
Definition: melee.cpp:1875
void perform_special_attacks(Creature &t, dealt_damage_instance &dealt_dam)
Performs special attacks and their effects (poisonous, stinger, etc.)
Definition: melee.cpp:1848
float hit_roll() const override
Returns the player's basic hit roll that is compared to the target's dodge roll.
Definition: melee.cpp:357
bool scored_crit(float target_dodge, const item &weap) const
Returns true if the player scores a critical hit.
Definition: melee.cpp:783
bool reach_attacking
Definition: character.h:621
void did_hit(Creature &target)
Handles special effects when the Character hits a Creature.
Definition: character.cpp:8291
void on_hit(Creature *source, bodypart_id bp_hit, dealt_projectile_attack const *proj) override
This creature just got hit by an attack - possibly special/ranged attack - from source.
Definition: character.cpp:8296
void perform_technique(const ma_technique &technique, Creature &t, damage_instance &di, int &move_cost)
Definition: melee.cpp:1426
std::string get_miss_reason()
Returns an explanation for why the player would miss a melee attack.
Definition: melee.cpp:389
void roll_all_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds all 3 types of physical damage to instance.
Definition: melee.cpp:411
bool is_quiet() const
Returns true if the player has quiet melee attacks.
virtual bool is_monster() const
Definition: creature.h:101
virtual Character * as_character()
Definition: creature.h:116
virtual int deal_melee_attack(Creature *source, int hitroll)
Definition: creature.cpp:504
virtual float dodge_roll()=0
virtual void deal_melee_hit(Creature *source, int hit_spread, bool critical_hit, const damage_instance &dam, dealt_damage_instance &dealt_dam)
Definition: creature.cpp:523
virtual bool is_dead_state() const =0
int reach_range(const Character &guy) const
Max range of melee attack this weapon can be used for.
Definition: item.cpp:5290
matec_id id
Definition: martialarts.h:97
std::string avatar_message
Definition: martialarts.h:112
bool made_of(const material_id &m) const override
Definition: monster.cpp:983
@ AEP_SAP_LIFE
Definition: enums.h:119
void player_hit_message(Character *attacker, const std::string &message, Creature &t, int dam, bool crit=false)
Definition: melee.cpp:2217
static const efftype_id effect_badpoison("badpoison")
std::string melee_message(const ma_technique &tec, Character &p, const dealt_damage_instance &ddi)
Definition: melee.cpp:2099
static const efftype_id effect_hit_by_player("hit_by_player")
int stumble(Character &u, const item &weap)
Definition: melee.cpp:767
static const trait_id trait_POISONOUS("POISONOUS")
static void melee_train(Character &p, int lo, int hi, const item &weap)
Definition: melee.cpp:419
static const trait_id trait_DEFT("DEFT")
static const efftype_id effect_poison("poison")
static const trait_id trait_POISONOUS2("POISONOUS2")
void smash_specific(monster *z, Creature *target)
Definition: monattack.cpp:1103
void generate_melee_sound(const tripoint &source, const tripoint &target, bool hit, bool targ_mon=false, const std::string &material="flesh")
Definition: sounds.cpp:1605
int actual_crit_count
Definition: melee.h:13

References _, melee_statistic_data::actual_crit_count, Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), AEP_SAP_LIFE, Creature::as_character(), item::attack_cost(), attack_cost(), melee_statistic_data::attack_count, ma_technique::avatar_message, bio_cqb, bp_arm_l, bp_arm_r, can_miss_recovery(), Creature::check_dead_state(), sounds::combat, melee_statistic_data::damage_amount, Creature::deal_melee_attack(), Creature::deal_melee_hit(), did_hit(), Creature::disp_name(), Creature::dodge_roll(), DT_CUT, DT_STAB, effect_badpoison, effect_hit_by_player, effect_poison, encumb(), g, sfx::generate_melee_sound(), get_miss_reason(), get_skill_level(), get_working_arm_count(), has_active_bionic(), has_artifact_with(), item::has_flag(), has_trait(), healall(), melee_statistic_data::hit_count, hit_roll(), ma_technique::id, Creature::is_dead_state(), Creature::is_monster(), is_mounted(), item::is_null(), Creature::is_player(), is_quiet(), m_bad, m_debug, m_good, m_info, m_neutral, monster::made_of(), martial_arts_data, melee_message(), melee_special_effects(), melee::melee_stats, melee_train(), mapgen_defer::message, MF_RIDEABLE_MECH, Creature::mod_moves(), mod_stamina(), mounted_creature, move_cost(), damage_instance::mult_damage(), name, string_id< T >::obj(), on_hit(), one_in(), perform_special_attacks(), perform_technique(), pick_technique(), player_hit_message(), Creature::pos(), pos(), primary_weapon(), reach_attacking, item::reach_range(), rng(), roll_all_damage(), roll_remainder(), scored_crit(), skill_melee, mattack::smash_specific(), sounds::sound(), stumble(), tec_none, dealt_damage_instance::total_damage(), trait_DEFT, trait_POISONOUS, trait_POISONOUS2, dealt_damage_instance::type_damage(), used_weapon(), and item::weight().

Referenced by block_hit(), npc::execute_action(), monexamine::mfriend_menu(), avatar_action::move(), npc::move_to(), game::npc_menu(), on_dodge(), perform_technique(), monexamine::pet_menu(), and reach_attack().

◆ melee_special_effects()

std::string Character::melee_special_effects ( Creature t,
damage_instance d,
item weap 
)

Handles combat effects, returns a string of any valid combat effect messages.

Strength increases chance of breaking glass weapons (NEGATIVE)

Definition at line 1875 of file melee.cpp.

1876{
1877 std::string dump;
1878
1879 std::string target = t.disp_name();
1880
1881 const bionic_id bio_shock( "bio_shock" );
1883 ( !is_armed() || primary_weapon().conductive() ) ) {
1885 d.add_damage( DT_ELECTRIC, rng( 2, 10 ) );
1886
1887 if( is_player() ) {
1888 dump += string_format( _( "You shock %s." ), target ) + "\n";
1889 } else {
1890 add_msg_if_npc( _( "<npcname> shocks %s." ), target );
1891 }
1892 }
1893
1894 const bionic_id bio_heat_absorb( "bio_heat_absorb" );
1895 if( has_active_bionic( bio_heat_absorb ) && !is_armed() && t.is_warm() ) {
1897 d.add_damage( DT_COLD, 3 );
1898 if( is_player() ) {
1899 dump += string_format( _( "You drain %s's body heat." ), target ) + "\n";
1900 } else {
1901 add_msg_if_npc( _( "<npcname> drains %s's body heat!" ), target );
1902 }
1903 }
1904
1905 if( primary_weapon().has_flag( "FLAMING" ) ) {
1906 d.add_damage( DT_HEAT, rng( 1, 8 ) );
1907
1908 if( is_player() ) {
1909 dump += string_format( _( "You burn %s." ), target ) + "\n";
1910 } else {
1911 add_msg_player_or_npc( _( "<npcname> burns %s." ), target );
1912 }
1913 }
1914
1915 //Hurting the wielder from poorly-chosen weapons
1916 if( weap.has_flag( "HURT_WHEN_WIELDED" ) && x_in_y( 2, 3 ) ) {
1917 add_msg_if_player( m_bad, _( "The %s cuts your hand!" ), weap.tname() );
1918 deal_damage( nullptr, bodypart_id( "hand_r" ), damage_instance::physical( 0,
1919 weap.damage_melee( DT_CUT ), 0 ) );
1920 if( weap.is_two_handed( *this ) ) { // Hurt left hand too, if it was big
1921 deal_damage( nullptr, bodypart_id( "hand_l" ), damage_instance::physical( 0,
1922 weap.damage_melee( DT_CUT ), 0 ) );
1923 }
1924 }
1925
1926 const int vol = weap.volume() / 250_ml;
1927 // Glass weapons shatter sometimes
1928 if( weap.made_of( material_id( "glass" ) ) &&
1929 /** @EFFECT_STR increases chance of breaking glass weapons (NEGATIVE) */
1930 rng( 0, vol + 8 ) < vol + str_cur ) {
1931 if( is_player() ) {
1932 dump += string_format( _( "Your %s shatters!" ), weap.tname() ) + "\n";
1933 } else {
1934 add_msg_player_or_npc( m_bad, _( "Your %s shatters!" ),
1935 _( "<npcname>'s %s shatters!" ),
1936 weap.tname() );
1937 }
1938
1939 sounds::sound( pos(), 16, sounds::sound_t::combat, "Crack!", true, "smash_success",
1940 "smash_glass_contents" );
1941 // Dump its contents on the ground
1942 weap.contents.spill_contents( pos() );
1943 // Take damage
1944 deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance::physical( 0, rng( 0, vol * 2 ),
1945 0 ) );
1946 if( weap.is_two_handed( *this ) ) { // Hurt left arm too, if it was big
1947 //redeclare shatter_dam because deal_damage mutates it
1948 deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance::physical( 0, rng( 0, vol * 2 ),
1949 0 ) );
1950 }
1951 d.add_damage( DT_CUT, rng( 0, 5 + static_cast<int>( vol * 1.5 ) ) ); // Hurt the monster extra
1952 remove_weapon();
1953 }
1954
1955 if( !t.is_hallucination() ) {
1956 handle_melee_wear( weap );
1957 }
1958
1959 // on-hit effects for martial arts
1960 martial_arts_data->ma_onhit_effects( *this );
1961
1962 return dump;
1963}
item remove_weapon()
Definition: character.cpp:2516
virtual bool is_warm() const
Definition: creature.cpp:987
int damage_melee(damage_type dt) const
Damage of given type caused when this item is used as melee weapon.
Definition: item.cpp:5213
static const bionic_id bio_shock("bio_shock")
static const bionic_id bio_heat_absorb("bio_heat_absorb")

References _, damage_instance::add_damage(), Creature::add_msg_if_npc(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), bio_heat_absorb, bio_shock, sounds::combat, item::contents, item::damage_melee(), deal_damage(), Creature::disp_name(), DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, get_power_level(), handle_melee_wear(), has_active_bionic(), Creature::has_flag(), item::has_flag(), is_armed(), Creature::is_hallucination(), Creature::is_player(), item::is_two_handed(), Creature::is_warm(), m_bad, item::made_of(), martial_arts_data, mod_power_level(), damage_instance::physical(), pos(), bionic_data::power_trigger, primary_weapon(), remove_weapon(), rng(), sounds::sound(), item_contents::spill_contents(), str_cur, string_format(), item::tname(), item::volume(), and x_in_y().

Referenced by melee_attack().

◆ mend()

void Character::mend ( int  rate_multiplier)

Handles the chance for broken limbs to spontaneously heal to 1 HP.

Definition at line 1672 of file suffer.cpp.

1673{
1674 // Wearing splints can slowly mend a broken limb back to 1 hp.
1675 bool any_broken = false;
1676 for( const bodypart_id &bp : get_all_body_parts() ) {
1677 if( is_limb_broken( bp ) ) {
1678 any_broken = true;
1679 break;
1680 }
1681 }
1682
1683 if( !any_broken ) {
1684 return;
1685 }
1686
1687 double healing_factor = 1.0;
1688 // Studies have shown that alcohol and tobacco use delay fracture healing time
1689 // Being under effect is 50% slowdown
1690 // Being addicted but not under effect scales from 25% slowdown to 75% slowdown
1691 // The improvement from being intoxicated over withdrawal is intended
1692 if( has_effect( effect_cig ) ) {
1693 healing_factor *= 0.5;
1694 } else {
1695 healing_factor *= addiction_scaling( 0.25f, 0.75f, addiction_level( add_type::CIG ) );
1696 }
1697
1698 if( has_effect( effect_drunk ) ) {
1699 healing_factor *= 0.5;
1700 } else {
1701 healing_factor *= addiction_scaling( 0.25f, 0.75f, addiction_level( add_type::ALCOHOL ) );
1702 }
1703
1704 if( get_rad() > 0 && !has_trait( trait_RADIOGENIC ) ) {
1705 healing_factor *= clamp( ( 1000.0f - get_rad() ) / 1000.0f, 0.0f, 1.0f );
1706 }
1707
1708 // Bed rest speeds up mending
1709 if( has_effect( effect_sleep ) ) {
1710 healing_factor *= 4.0;
1711 } else if( get_fatigue() > fatigue_levels::dead_tired ) {
1712 // but being dead tired does not...
1713 healing_factor *= 0.75;
1714 } else {
1715 // If not dead tired, resting without sleep also helps
1716 healing_factor *= 1.0f + rest_quality();
1717 }
1718
1719 // Being healthy helps.
1720 healing_factor *= 1.0f + get_healthy() / 200.0f;
1721
1722 // Very hungry starts lowering the chance
1723 // square rooting the value makes the numbers drop off faster when below 1
1724 healing_factor *= std::sqrt( static_cast<float>( get_stored_kcal() ) / static_cast<float>
1725 ( max_stored_kcal() ) );
1726 // Similar for thirst - starts at very thirsty, drops to 0 at parched
1727 healing_factor *= 1.0f - clamp( 1.0f * ( get_thirst() - thirst_levels::very_thirsty ) /
1728 +thirst_levels::parched, 0.0f, 1.0f );
1729
1730 // Mutagenic healing factor!
1731 bool needs_splint = true;
1732
1733 healing_factor *= mutation_value( "mending_modifier" );
1734
1735 if( has_trait( trait_REGEN_LIZ ) ) {
1736 needs_splint = false;
1737 }
1738
1739 add_msg( m_debug, "Limb mend healing factor: %.2f", healing_factor );
1740 if( healing_factor <= 0.0f ) {
1741 // The section below assumes positive healing rate
1742 return;
1743 }
1744
1745 for( const bodypart_id &bp : get_all_body_parts() ) {
1746 const bool broken = is_limb_broken( bp );
1747 if( !broken ) {
1748 continue;
1749 }
1750
1751 if( needs_splint && !worn_with_flag( flag_SPLINT, bp ) ) {
1752 continue;
1753 }
1754
1755 const time_duration dur_inc = 1_turns * roll_remainder( rate_multiplier * healing_factor );
1756 auto &eff = get_effect( effect_mending, bp->token );
1757 if( eff.is_null() ) {
1758 add_effect( effect_mending, dur_inc, bp->token );
1759 continue;
1760 }
1761
1762 eff.set_duration( eff.get_duration() + dur_inc );
1763
1764 if( eff.get_duration() >= eff.get_max_duration() ) {
1765 set_part_hp_cur( bp, 1 );
1766 remove_effect( effect_mending, bp->token );
1767 g->events().send<event_type::broken_bone_mends>( getID(), bp->token );
1768 //~ %s is bodypart
1769 add_msg_if_player( m_good, _( "Your %s has started to mend!" ),
1770 body_part_name( bp ) );
1771 }
1772 }
1773}
float rest_quality() const
Returns >0 if character is sitting/lying and relatively inactive.
Definition: character.cpp:6447
int addiction_level(add_type type) const
Returns the intensity of the specified addiction.
Definition: suffer.cpp:2028
@ broken
Definition: enums.h:330
static const efftype_id effect_drunk("drunk")
static const trait_id trait_REGEN_LIZ("REGEN_LIZ")
static const efftype_id effect_cig("cig")
static const efftype_id effect_sleep("sleep")
static const std::string flag_SPLINT("SPLINT")
static float addiction_scaling(float at_min, float at_max, float add_lvl)
Definition: suffer.cpp:177
static const efftype_id effect_mending("mending")
static const trait_id trait_RADIOGENIC("RADIOGENIC")

References _, Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), addiction_level(), addiction_scaling(), ALCOHOL, body_part_name(), broken, broken_bone_mends, CIG, clamp(), dead_tired, effect_cig, effect_drunk, effect_mending, effect_sleep, flag_SPLINT(), g, Creature::get_all_body_parts(), Creature::get_effect(), get_fatigue(), get_healthy(), get_rad(), get_stored_kcal(), get_thirst(), getID(), Creature::has_effect(), has_trait(), is_limb_broken(), m_debug, m_good, max_stored_kcal(), mutation_value(), parched, Creature::remove_effect(), rest_quality(), roll_remainder(), Creature::set_part_hp_cur(), trait_RADIOGENIC, trait_REGEN_LIZ, very_thirsty, and worn_with_flag().

Referenced by update_body().

◆ metabolic_rate()

float Character::metabolic_rate ( ) const

Current metabolic rate due to traits, hunger, speed, etc.

Definition at line 614 of file consumption.cpp.

615{
616 return metabolic_rate_base();
617}

References metabolic_rate_base().

Referenced by calc_needs_rates().

◆ metabolic_rate_base()

float Character::metabolic_rate_base ( ) const

Stable base metabolic rate due to traits.

Definition at line 601 of file consumption.cpp.

602{
603 static const std::string hunger_rate_string( "PLAYER_HUNGER_RATE" );
604 static const std::string metabolism_modifier( "metabolism_modifier" );
605
606 float hunger_rate = get_option< float >( hunger_rate_string );
607 float mut_bonus = 1.0f + mutation_value( metabolism_modifier );
608 float with_mut = hunger_rate * mut_bonus;
609 float ench_bonus = bonus_from_enchantments( with_mut, enchant_vals::mod::METABOLISM );
610
611 return std::max( 0.0f, with_mut + ench_bonus );
612}

References bonus_from_enchantments(), enchant_vals::METABOLISM, and mutation_value().

Referenced by bmr(), and metabolic_rate().

◆ mod_base_age()

void Character::mod_base_age ( int  mod)

Definition at line 6788 of file character.cpp.

6789{
6790 init_age += mod;
6791}

References init_age.

Referenced by set_description().

◆ mod_base_height()

void Character::mod_base_height ( int  mod)

Definition at line 6817 of file character.cpp.

6818{
6819 init_height += mod;
6820}

References init_height.

Referenced by set_description().

◆ mod_dex_bonus()

void Character::mod_dex_bonus ( int  ndex)
virtual

◆ mod_fatigue()

◆ mod_healthy()

void Character::mod_healthy ( int  nhealthy)
virtual

Modifiers for health values exclusive to characters.

Definition at line 4270 of file character.cpp.

4271{
4272 float mut_rate = 1.0f;
4273 for( const trait_id &mut : get_mutations() ) {
4274 mut_rate *= mut.obj().healthy_rate;
4275 }
4276 healthy += nhealthy * mut_rate;
4277}

References get_mutations(), and healthy.

Referenced by iuse::adrenaline_injector(), mod_stat(), process_one_effect(), spell_effect::recover_energy(), and update_health().

◆ mod_healthy_mod()

void Character::mod_healthy_mod ( int  nhealthy_mod,
int  cap 
)
virtual

Definition at line 4282 of file character.cpp.

4283{
4284 // TODO: This really should be a full morale-like system, with per-effect caps
4285 // and durations. This version prevents any single effect from exceeding its
4286 // intended ceiling, but multiple effects will overlap instead of adding.
4287
4288 // Cap indicates how far the mod is allowed to shift in this direction.
4289 // It can have a different sign to the mod, e.g. for items that treat
4290 // extremely low health, but can't make you healthy.
4291 if( nhealthy_mod == 0 || cap == 0 ) {
4292 return;
4293 }
4294 int low_cap;
4295 int high_cap;
4296 if( nhealthy_mod < 0 ) {
4297 low_cap = cap;
4298 high_cap = 200;
4299 } else {
4300 low_cap = -200;
4301 high_cap = cap;
4302 }
4303
4304 // If we're already out-of-bounds, we don't need to do anything.
4305 if( ( healthy_mod <= low_cap && nhealthy_mod < 0 ) ||
4306 ( healthy_mod >= high_cap && nhealthy_mod > 0 ) ) {
4307 return;
4308 }
4309
4310 healthy_mod += nhealthy_mod;
4311
4312 // Since we already bailed out if we were out-of-bounds, we can
4313 // just clamp to the boundaries here.
4314 healthy_mod = std::min( healthy_mod, high_cap );
4315 healthy_mod = std::max( healthy_mod, low_cap );
4316}

References healthy_mod.

Referenced by addict_effect(), iuse::blech(), check_needs_extremes(), consume_effects(), hardcoded_effects(), modify_health(), iuse::mycus(), iuse::plantblech(), process_one_effect(), rooted(), suffer_feral_kill_withdrawl(), suffer_from_bad_bionics(), suffer_from_other_mutations(), update_health(), and iuse::vaccine().

◆ mod_int_bonus()

void Character::mod_int_bonus ( int  nint)
virtual

◆ mod_max_power_level()

void Character::mod_max_power_level ( const units::energy npower_max)

Definition at line 1936 of file character.cpp.

1937{
1938 max_power_level += npower_max;
1939}

References max_power_level.

Referenced by add_bionic(), perform_uninstall(), and uninstall_bionic().

◆ mod_pain()

void Character::mod_pain ( int  npain)
overridevirtual

Modifies a pain value by player traits before passing it to Creature::mod_pain()

Reimplemented from Creature.

Definition at line 764 of file character.cpp.

765{
766 if( npain > 0 ) {
768 return;
769 }
770 // always increase pain gained by one from these bad mutations
771 if( has_trait( trait_MOREPAIN ) ) {
772 npain += std::max( 1, roll_remainder( npain * 0.25 ) );
773 } else if( has_trait( trait_MOREPAIN2 ) ) {
774 npain += std::max( 1, roll_remainder( npain * 0.5 ) );
775 } else if( has_trait( trait_MOREPAIN3 ) ) {
776 npain += std::max( 1, roll_remainder( npain * 1.0 ) );
777 }
778
779 if( npain > 1 ) {
780 // if it's 1 it'll just become 0, which is bad
782 npain = roll_remainder( npain * 0.5 );
783 } else if( has_trait( trait_PAINRESIST ) ) {
784 npain = roll_remainder( npain * 0.67 );
785 }
786 }
787 }
788 Creature::mod_pain( npain );
789}
static const efftype_id effect_narcosis("narcosis")
static const trait_id trait_MOREPAIN("MORE_PAIN")
static const trait_id trait_PAINRESIST_TROGLO("PAINRESIST_TROGLO")
static const trait_id trait_MOREPAIN2("MORE_PAIN2")
static const trait_id trait_PAINRESIST("PAINRESIST")
static const trait_id trait_MOREPAIN3("MORE_PAIN3")
virtual void mod_pain(int npain)
Definition: creature.cpp:1387

References effect_narcosis, Creature::has_effect(), has_trait(), Creature::mod_pain(), roll_remainder(), trait_MOREPAIN, trait_MOREPAIN2, trait_MOREPAIN3, trait_NOPAIN, trait_PAINRESIST, and trait_PAINRESIST_TROGLO.

Referenced by addict_effect(), iuse::antiparasitic(), apply_damage(), iexamine::autodoc(), iuse::blech(), iuse::blood_draw(), blood_magic(), burn_move_stamina(), activity_handlers::burrow_finish(), cauterize_actor::cauterize_effect(), debug_menu::character_edit_menu(), consume_effects(), eff_fun_bleed(), iuse::ehandcuffs(), game::find_or_make_stairs(), game::grabbed_furn_move(), game::grabbed_veh_move(), hardcoded_effects(), hurtall(), marloss_common(), game::mon_info_update(), iuse::mycus(), activity_handlers::pickaxe_finish(), map::player_in_field(), process_bionic(), process_one_effect(), sounds::process_sound_markers(), iuse::purify_iv(), iuse::purify_smart(), spell_effect::recover_energy(), regen(), suffer_feral_kill_withdrawl(), suffer_from_bad_bionics(), suffer_from_chemimbalance(), suffer_from_sunburn(), suffer_without_sleep(), try_reject_mutagen(), update_needs(), mutagen_actor::use(), mutagen_iv_actor::use(), and iuse::vaccine().

◆ mod_painkiller()

void Character::mod_painkiller ( int  npkill)

◆ mod_per_bonus()

void Character::mod_per_bonus ( int  nper)
virtual

◆ mod_power_level()

void Character::mod_power_level ( const units::energy npower)

Definition at line 1924 of file character.cpp.

1925{
1926 // Remaining capacity between current and maximum power levels we can make use of.
1927 const units::energy remaining_capacity = get_max_power_level() - get_power_level();
1928 // We can't add more than remaining capacity, so get the minimum of the two
1929 const units::energy minned_npower = std::min( npower, remaining_capacity );
1930 // new candidate power level
1931 const units::energy new_power = get_power_level() + minned_npower;
1932 // set new power level while prevending it from going negative
1933 set_power_level( std::max( 0_kJ, new_power ) );
1934}

References get_max_power_level(), get_power_level(), and set_power_level().

Referenced by activate_bionic(), item::ammo_consume(), burn_fuel(), deactivate_bionic(), npc::discharge_cbm_weapon(), do_skill_rust(), iuse::ehandcuffs(), explosion_handler::emp_blast(), feed_furnace_with(), aim_activity_actor::finish(), iexamine::fireplace(), hack_attempt(), melee_special_effects(), modify_morale(), game::monmove(), on_hit(), game::on_move_effects(), passive_power_gen(), game::phasing_move(), process_bionic(), npc::recharge_cbm(), spell_effect::recover_energy(), mattack::riotbot(), activity_handlers::spellcasting_finish(), suffer_from_asthma(), suffer_from_bad_bionics(), suffer_from_radiation(), suffer_while_underwater(), try_start_hacking(), character_funcs::try_uncanny_dodge(), update_stamina(), use_charges(), and use_fire().

◆ mod_rad()

void Character::mod_rad ( int  mod)

Definition at line 7078 of file character.cpp.

7079{
7080 if( has_trait_flag( "NO_RADIATION" ) ) {
7081 return;
7082 }
7083 set_rad( std::max( 0, get_rad() + mod ) );
7084}

References get_rad(), has_trait_flag(), and set_rad().

Referenced by irradiate(), game::process_artifact(), process_bionic(), process_one_effect(), regen(), and suffer_from_radiation().

◆ mod_skill_level()

void Character::mod_skill_level ( const skill_id ident,
int  delta 
)

Definition at line 3364 of file character.cpp.

3365{
3366 _skills->mod_skill_level( ident, delta );
3367}

References _skills.

Referenced by avatar::create(), npc::randomize(), and set_skills().

◆ mod_sleep_deprivation()

void Character::mod_sleep_deprivation ( int  nsleep_deprivation)
virtual

Definition at line 4459 of file character.cpp.

4460{
4461 set_sleep_deprivation( sleep_deprivation + nsleep_deprivation );
4462}

References set_sleep_deprivation(), and sleep_deprivation.

Referenced by update_needs().

◆ mod_stamina()

◆ mod_stat()

void Character::mod_stat ( const std::string &  stat,
float  modifier 
)
overridevirtual

Reimplemented from Creature.

Definition at line 546 of file character.cpp.

547{
548 if( stat == "str" ) {
549 mod_str_bonus( modifier );
550 } else if( stat == "dex" ) {
551 mod_dex_bonus( modifier );
552 } else if( stat == "per" ) {
553 mod_per_bonus( modifier );
554 } else if( stat == "int" ) {
555 mod_int_bonus( modifier );
556 } else if( stat == "healthy" ) {
557 mod_healthy( modifier );
558 } else if( stat == "kcal" ) {
559 mod_stored_kcal( modifier );
560 } else if( stat == "hunger" ) {
561 mod_stored_kcal( -10 * modifier );
562 } else if( stat == "thirst" ) {
563 mod_thirst( modifier );
564 } else if( stat == "fatigue" ) {
565 mod_fatigue( modifier );
566 } else if( stat == "oxygen" ) {
567 oxygen += modifier;
568 } else if( stat == "stamina" ) {
569 mod_stamina( modifier );
570 } else {
571 Creature::mod_stat( stat, modifier );
572 }
573}
virtual void mod_healthy(int nhealthy)
Modifiers for health values exclusive to characters.
Definition: character.cpp:4270
virtual void mod_stat(const std::string &stat, float modifier)
Definition: creature.cpp:1746

References mod_dex_bonus(), mod_fatigue(), mod_healthy(), mod_int_bonus(), mod_per_bonus(), mod_stamina(), Creature::mod_stat(), mod_stored_kcal(), mod_str_bonus(), mod_thirst(), and oxygen.

Referenced by apply_skill_boost(), shout(), and consume_drug_iuse::use().

◆ mod_stim()

◆ mod_stored_kcal()

◆ mod_stored_nutr()

void Character::mod_stored_nutr ( int  nnutr)
virtual

◆ mod_str_bonus()

void Character::mod_str_bonus ( int  nstr)
virtual

◆ mod_thirst()

◆ modify_addiction()

void Character::modify_addiction ( const islot_comestible comest)

Used to apply addiction modifications from food and medication.

Definition at line 1064 of file consumption.cpp.

1065{
1066 add_addiction( comest.add, comest.addict );
1067 if( addiction_craving( comest.add ) != MORALE_NULL ) {
1068 rem_morale( addiction_craving( comest.add ) );
1069 }
1070}
morale_type addiction_craving(add_type const cur)
Definition: addiction.cpp:307
void add_addiction(add_type type, int strength)
Adds an addiction to the player.
Definition: suffer.cpp:1959
add_type add
effects of addiction
Definition: itype.h:142
int addict
addiction potential
Definition: itype.h:139

References islot_comestible::add, add_addiction(), islot_comestible::addict, addiction_craving(), MORALE_NULL, and rem_morale().

Referenced by consume_effects(), and consume_med().

◆ modify_fatigue()

void Character::modify_fatigue ( const islot_comestible comest)

Used to apply fatigue modifications from food and medication.

Definition at line 1054 of file consumption.cpp.

1055{
1056 mod_fatigue( -comest.fatigue_mod );
1057}
int fatigue_mod
fatigue altering effect
Definition: itype.h:148

References islot_comestible::fatigue_mod, and mod_fatigue().

Referenced by consume_effects(), and consume_med().

◆ modify_health()

void Character::modify_health ( const islot_comestible comest)

Used to apply health modifications from food and medication.

Definition at line 1011 of file consumption.cpp.

1012{
1013 const int effective_health = comest.healthy;
1014 // Effectively no cap on health modifiers from food and meds
1015 const int health_cap = 200;
1016 mod_healthy_mod( effective_health, effective_health >= 0 ? health_cap : -health_cap );
1017}
int healthy
TODO: add documentation.
Definition: itype.h:157

References islot_comestible::healthy, and mod_healthy_mod().

Referenced by consume_effects(), and consume_med().

◆ modify_morale()

void Character::modify_morale ( item food,
int  nutr = 0 
)

Used to apply morale modifications from food and medication.

Definition at line 1072 of file consumption.cpp.

1073{
1074 time_duration morale_time = 2_hours;
1075 if( food.has_flag( flag_EATEN_HOT ) ) {
1076 auto heater = find_food_heater( *this, crafting_inventory(),
1077 get_map().has_nearby_fire( pos(), PICKUP_RANGE ) );
1078 if( heater && heater->consume( *this ) ) {
1080 _( "You heat up your %1$s using the %2$s." ),
1081 _( "<npcname> heats up their %1$s using the %2$s." ),
1082 food.tname(), heater->it.tname() );
1083 food.unset_flag( flag_COLD );
1084 food.unset_flag( flag_VERY_COLD );
1085 morale_time = 3_hours;
1086 int clamped_nutr = std::max( 5, std::min( 20, nutr / 10 ) );
1087 add_morale( MORALE_FOOD_HOT, clamped_nutr, 20, morale_time, morale_time / 2 );
1088 }
1089 }
1090
1091 std::pair<int, int> fun = fun_for( food );
1092 if( fun.first < 0 ) {
1094 get_power_level() > units::from_kilojoule( -fun.first ) ) {
1095 mod_power_level( units::from_kilojoule( std::min( 0, fun_for( food ).first ) ) );
1096 } else {
1097 add_morale( MORALE_FOOD_BAD, fun.first, fun.second, morale_time, morale_time / 2, false,
1098 food.type );
1099 }
1100 } else if( fun.first > 0 ) {
1101 add_morale( MORALE_FOOD_GOOD, fun.first, fun.second, morale_time, morale_time / 2, false,
1102 food.type );
1103 }
1104
1105 if( food.has_flag( flag_HIDDEN_HALLU ) ) {
1106 if( has_trait( trait_SPIRITUAL ) ) {
1107 add_morale( MORALE_FOOD_GOOD, 36, 72, 2_hours, 1_hours, false );
1108 } else {
1109 add_morale( MORALE_FOOD_GOOD, 18, 36, 1_hours, 30_minutes, false );
1110 }
1111 }
1112
1113 if( food.has_flag( flag_CANNIBALISM ) ) {
1114 const bool cannibal = has_trait( trait_CANNIBAL );
1115 const bool psycho = has_trait( trait_PSYCHOPATH );
1116 const bool sapiovore = has_trait( trait_SAPIOVORE );
1117 if( cannibal ) {
1118 add_msg_if_player( m_good, _( "You indulge your shameful hunger." ) );
1119 add_morale( MORALE_CANNIBAL, 20, 200 );
1120 } else if( psycho || sapiovore ) {
1121 // Nothing - doesn't care enough to print a message
1122 } else {
1123 add_msg_if_player( m_bad, _( "You feel horrible for eating a person." ) );
1124 add_morale( MORALE_CANNIBAL, -60, -400, 60_minutes, 30_minutes );
1125 }
1126 }
1127
1128 // Allergy check for food that is ingested (not gum)
1129 if( !food.has_flag( "NO_INGEST" ) ) {
1130 const auto allergy = allergy_type( food );
1131 if( allergy != MORALE_NULL ) {
1132 add_msg_if_player( m_bad, _( "Yuck! How can anybody eat this stuff?" ) );
1133 add_morale( allergy, -75, -400, 30_minutes, 24_minutes );
1134 }
1135 if( food.has_flag( flag_ALLERGEN_JUNK ) ) {
1136 if( has_trait( trait_PROJUNK ) ) {
1137 add_msg_if_player( m_good, _( "Mmm, junk food." ) );
1138 add_morale( MORALE_SWEETTOOTH, 5, 30, 30_minutes, 24_minutes );
1139 }
1140 if( has_trait( trait_PROJUNK2 ) ) {
1141 if( !one_in( 100 ) ) {
1142 add_msg_if_player( m_good, _( "When life's got you down, there's always sugar." ) );
1143 } else {
1144 add_msg_if_player( m_good, _( "They may do what they must… you've already won." ) );
1145 }
1146 add_morale( MORALE_SWEETTOOTH, 10, 50, 1_hours, 50_minutes );
1147 }
1148 // Carnivores CAN eat junk food, but they won't like it much.
1149 // Pizza-scraping happens in consume_effects.
1151 add_msg_if_player( m_bad, _( "Your stomach begins gurgling and you feel bloated and ill." ) );
1152 add_morale( MORALE_NO_DIGEST, -25, -125, 30_minutes, 24_minutes );
1153 }
1154 }
1155 }
1156 const bool chew = food.get_comestible()->comesttype == comesttype_FOOD ||
1158 if( !food.rotten() && chew && has_trait( trait_SAPROPHAGE ) ) {
1159 // It's OK to *drink* things that haven't rotted. Alternative is to ban water. D:
1160 add_msg_if_player( m_bad, _( "Your stomach begins gurgling and you feel bloated and ill." ) );
1161 add_morale( MORALE_NO_DIGEST, -75, -400, 30_minutes, 24_minutes );
1162 }
1163 if( food.has_flag( flag_URSINE_HONEY ) && ( !crossed_threshold() ||
1165 mutation_category_level["URSINE"] > 40 ) {
1166 // Need at least 5 bear mutations for effect to show, to filter out mutations in common with other categories
1167 int honey_fun = has_trait( trait_THRESH_URSINE ) ?
1168 std::min( mutation_category_level["URSINE"] / 8, 20 ) :
1169 mutation_category_level["URSINE"] / 12;
1170 if( honey_fun < 10 ) {
1171 add_msg_if_player( m_good, _( "You find the sweet taste of honey surprisingly palatable." ) );
1172 } else {
1173 add_msg_if_player( m_good, _( "You feast upon the sweet honey." ) );
1174 }
1175 add_morale( MORALE_HONEY, honey_fun, 100 );
1176 }
1177}
morale_type allergy_type(const item &food) const
Returns allergy type or MORALE_NULL if not allergic for this character.
std::pair< int, int > fun_for(const item &comest) const
Handles the enjoyability value for a comestible.
item & unset_flag(const std::string &flag)
Idempotent filter removing an item specific flag.
Definition: item.cpp:5363
static const bionic_id bio_taste_blocker("bio_taste_blocker")
static const trait_id trait_THRESH_URSINE("THRESH_URSINE")
static const std::string flag_URSINE_HONEY("URSINE_HONEY")
static std::optional< prepared_item_consumption > find_food_heater(Character &c, const inventory &inv, bool has_fire)
static const std::string flag_CANNIBALISM("CANNIBALISM")
static const trait_id trait_SAPIOVORE("SAPIOVORE")
static const trait_id trait_PSYCHOPATH("PSYCHOPATH")
static const trait_id trait_PROJUNK("PROJUNK")
static const trait_id trait_SPIRITUAL("SPIRITUAL")
static const std::string flag_EATEN_HOT("EATEN_HOT")
static const trait_id trait_CANNIBAL("CANNIBAL")
const morale_type MORALE_HONEY("morale_honey")
const morale_type MORALE_SWEETTOOTH("morale_sweettooth")
const morale_type MORALE_NO_DIGEST("morale_no_digest")
const morale_type MORALE_FOOD_HOT("morale_food_hot")
const morale_type MORALE_FOOD_GOOD("morale_food_good")
const morale_type MORALE_CANNIBAL("morale_cannibal")
const morale_type MORALE_FOOD_BAD("morale_food_bad")

References _, add_morale(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), allergy, allergy_type(), bio_taste_blocker, iuse::chew(), comesttype_FOOD(), crafting_inventory(), crossed_threshold(), find_food_heater(), flag_ALLERGEN_JUNK(), flag_CANNIBALISM(), flag_CARNIVORE_OK(), flag_COLD(), flag_EATEN_HOT(), flag_HIDDEN_HALLU(), flag_URSINE_HONEY(), flag_USE_EAT_VERB(), flag_VERY_COLD(), units::from_kilojoule(), fun_for(), item::get_comestible(), get_map(), get_power_level(), has_active_bionic(), item::has_flag(), has_trait(), m_bad, m_good, mod_power_level(), MORALE_CANNIBAL, MORALE_FOOD_BAD, MORALE_FOOD_GOOD, MORALE_FOOD_HOT, MORALE_HONEY, MORALE_NO_DIGEST, MORALE_NULL, MORALE_SWEETTOOTH, mutation_category_level, one_in(), PICKUP_RANGE, pos(), item::rotten(), item::tname(), trait_CANNIBAL, trait_CARNIVORE, trait_PROJUNK, trait_PROJUNK2, trait_PSYCHOPATH, trait_SAPIOVORE, trait_SAPROPHAGE, trait_SPIRITUAL, trait_THRESH_URSINE, item::type, and item::unset_flag().

Referenced by consume_effects(), and consume_med().

◆ modify_radiation()

void Character::modify_radiation ( const islot_comestible comest)

Used to apply radiation from food and medication.

Definition at line 1059 of file consumption.cpp.

1060{
1061 irradiate( comest.radiation );
1062}
int radiation
Amount of radiation you get from this comestible.
Definition: itype.h:163

References irradiate(), and islot_comestible::radiation.

Referenced by consume_effects(), and consume_med().

◆ modify_stimulation()

void Character::modify_stimulation ( const islot_comestible comest)

Used to apply stimulation modifications from food and medication.

Definition at line 1019 of file consumption.cpp.

1020{
1021 const int current_stim = get_stim();
1022 if( comest.stim != 0 &&
1023 ( std::abs( current_stim ) < ( std::abs( comest.stim ) * 3 ) ||
1024 sgn( current_stim ) != sgn( comest.stim ) ) ) {
1025 if( comest.stim < 0 ) {
1026 set_stim( std::max( comest.stim * 3, current_stim + comest.stim ) );
1027 } else {
1028 set_stim( std::min( comest.stim * 3, current_stim + comest.stim ) );
1029 }
1030 }
1031 if( has_trait( trait_STIMBOOST ) && ( current_stim > 30 ) &&
1032 ( ( comest.add == add_type::CAFFEINE ) || ( comest.add == add_type::SPEED ) ||
1033 ( comest.add == add_type::COKE ) || ( comest.add == add_type::CRACK ) ) ) {
1034 int hallu_duration = ( current_stim - comest.stim < 30 ) ? current_stim - 30 : comest.stim;
1035 add_effect( effect_visuals, hallu_duration * 30_minutes );
1036 std::vector<std::string> stimboost_msg{ _( "The shadows are getting ever closer." ),
1037 _( "You have a bad feeling about this." ),
1038 _( "A powerful sense of dread comes over you." ),
1039 _( "Your skin starts crawling." ),
1040 _( "They're coming to get you." ),
1041 _( "This might've been a bad idea…" ),
1042 _( "You've really done it this time, haven't you?" ),
1043 _( "You have to stay vigilant. They're always watching…" ),
1044 _( "mistake mistake mistake mistake mistake" ),
1045 _( "Just gotta stay calm, and you'll make it through this." ),
1046 _( "You're starting to feel very jumpy." ),
1047 _( "Something is twitching at the edge of your vision." ),
1048 _( "They know what you've done…" ),
1049 _( "You're feeling even more paranoid than usual." ) };
1050 add_msg_if_player( m_bad, random_entry_ref( stimboost_msg ) );
1051 }
1052}
static const efftype_id effect_visuals("visuals")
static const trait_id trait_STIMBOOST("STIMBOOST")
constexpr int sgn(const T x)
Definition: enums.h:8
std::enable_if<!is_std_array< C >::value, constV & >::type random_entry_ref(const C &container)
Same as above, but with a statically allocated default value (using the default constructor).
Definition: rng.h:149
int stim
stimulant effect
Definition: itype.h:145

References _, islot_comestible::add, Creature::add_effect(), Creature::add_msg_if_player(), CAFFEINE, COKE, CRACK, effect_visuals, get_stim(), has_trait(), m_bad, random_entry_ref(), set_stim(), sgn(), SPEED, islot_comestible::stim, and trait_STIMBOOST.

Referenced by consume_effects(), and consume_med().

◆ mount_creature()

void Character::mount_creature ( monster z)

Definition at line 968 of file character.cpp.

969{
970 tripoint pnt = z.pos();
971 shared_ptr_fast<monster> mons = g->shared_from( z );
972 if( mons == nullptr ) {
973 add_msg( m_debug, "mount_creature(): monster not found in critter_tracker" );
974 return;
975 }
976 add_effect( effect_riding, 1_turns, num_bp );
977 z.add_effect( effect_ridden, 1_turns, num_bp );
978 if( z.has_effect( effect_tied ) ) {
980 if( z.tied_item ) {
981 i_add( *z.tied_item );
982 z.tied_item.reset();
983 }
984 }
986 if( z.has_effect( effect_harnessed ) ) {
988 add_msg_if_player( m_info, _( "You remove the %s's harness." ), z.get_name() );
989 }
990 mounted_creature = mons;
991 mons->mounted_player = this;
992 if( is_avatar() ) {
993 if( g->u.is_hauling() ) {
994 g->u.stop_hauling();
995 }
996 if( g->u.get_grab_type() != OBJECT_NONE ) {
997 add_msg( m_warning, _( "You let go of the grabbed object." ) );
998 g->u.grab( OBJECT_NONE );
999 }
1000 g->place_player( pnt );
1001 } else {
1002 npc &guy = dynamic_cast<npc &>( *this );
1003 guy.setpos( pnt );
1004 }
1005 z.facing = facing;
1006 // Make sure something didn't interrupt this process and knock the player off partway through!
1007 if( has_effect( effect_riding ) ) {
1008 add_msg_if_player( m_good, _( "You climb on the %s." ), z.get_name() );
1009 if( z.has_flag( MF_RIDEABLE_MECH ) ) {
1010 if( !z.type->mech_weapon.is_empty() ) {
1011 auto mechwep = item{ z.type->mech_weapon };
1012 wield( mechwep );
1013 }
1014 add_msg_if_player( m_good, _( "You hear your %s whir to life." ), z.get_name() );
1015 }
1016 add_msg_if_player( m_good, _( "You hear your %s whir to life." ), z.get_name() );
1017 }
1018 // some rideable mechs have night-vision
1020 mod_moves( -100 );
1021}
static const efftype_id effect_tied("tied")
static const efftype_id effect_harnessed("harnessed")
FacingDirection facing
return the direction the creature is facing, for sdl horizontal flip
Definition: creature.h:135
cata::value_ptr< item > tied_item
Definition: monster.h:461
std::string get_name() const override
Definition: monster.cpp:484
void setpos(const tripoint &pos) override
Note: this places NPC on a given position in CURRENT MAP coordinates.
Definition: npc.cpp:693
std::shared_ptr< T > shared_ptr_fast
Definition: memory_fast.h:16

References _, Creature::add_effect(), monster::add_effect(), add_msg(), Creature::add_msg_if_player(), effect_harnessed, effect_ridden, effect_riding, effect_tied, Creature::facing, g, monster::get_name(), getID(), Creature::has_effect(), monster::has_flag(), i_add(), Creature::is_avatar(), string_id< T >::is_empty(), m_debug, m_good, m_info, m_warning, mtype::mech_weapon, MF_RIDEABLE_MECH, Creature::mod_moves(), mounted_creature, monster::mounted_player_id, num_bp, OBJECT_NONE, monster::pos(), recalc_sight_limits(), Creature::remove_effect(), npc::setpos(), monster::tied_item, monster::type, and wield().

Referenced by activity_handlers::find_mount_do_turn(), and monexamine::mount_pet().

◆ move_effects()

bool Character::move_effects ( bool  attacking)
overridevirtual

Processes effects which may prevent the Character from moving (bear traps, crushed, etc.).

Returns false if movement is stopped.

Strength increases chance to escape pit Dexterity increases chance to escape pit, slightly

Implements Creature.

Definition at line 1475 of file character.cpp.

1476{
1477 if( has_effect( effect_downed ) ) {
1478 try_remove_downed( *this );
1479 return false;
1480 }
1481 if( has_effect( effect_webbed ) ) {
1482 try_remove_webs( *this );
1483 return false;
1484 }
1485 if( has_effect( effect_lightsnare ) ) {
1486 try_remove_lightsnare( *this );
1487 return false;
1488
1489 }
1490 if( has_effect( effect_heavysnare ) ) {
1491 try_remove_heavysnare( *this );
1492 return false;
1493 }
1494 if( has_effect( effect_beartrap ) ) {
1495 try_remove_bear_trap( *this );
1496 return false;
1497 }
1498 if( has_effect( effect_crushed ) ) {
1499 try_remove_crushed( *this );
1500 return false;
1501 }
1502 // Below this point are things that allow for movement if they succeed
1503
1504 // Currently we only have one thing that forces movement if you succeed, should we get more
1505 // than this will need to be reworked to only have success effects if /all/ checks succeed
1506 if( has_effect( effect_in_pit ) ) {
1507 /** @EFFECT_STR increases chance to escape pit */
1508
1509 /** @EFFECT_DEX increases chance to escape pit, slightly */
1510 if( rng( 0, 40 ) > get_str() + get_dex() / 2 ) {
1511 add_msg_if_player( m_bad, _( "You try to escape the pit, but slip back in." ) );
1512 return false;
1513 } else {
1514 add_msg_player_or_npc( m_good, _( "You escape the pit!" ),
1515 _( "<npcname> escapes the pit!" ) );
1517 }
1518 }
1519 if( has_effect( effect_grabbed ) && !attacking && !try_remove_grab( *this ) ) {
1520 // NOLINTNEXTLINE(readability-simplify-boolean-expr)
1521 return false;
1522 }
1523 return true;
1524}
static void try_remove_lightsnare(Character &c)
Definition: character.cpp:1325
static void try_remove_crushed(Character &c)
Definition: character.cpp:1385
static const efftype_id effect_crushed("crushed")
static void try_remove_heavysnare(Character &c)
Definition: character.cpp:1354
static void try_remove_bear_trap(Character &c)
Definition: character.cpp:1289
static void try_remove_webs(Character &c)
Definition: character.cpp:1455
static bool try_remove_grab(Character &c)
Definition: character.cpp:1399
static const efftype_id effect_webbed("webbed")
static const efftype_id effect_in_pit("in_pit")
static void try_remove_downed(Character &c)
Definition: character.cpp:1274

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), effect_beartrap, effect_crushed, effect_downed, effect_grabbed, effect_heavysnare, effect_in_pit, effect_lightsnare, effect_webbed, get_dex(), get_str(), Creature::has_effect(), m_bad, m_good, Creature::remove_effect(), rng(), try_remove_bear_trap(), try_remove_crushed(), try_remove_downed(), try_remove_grab(), try_remove_heavysnare(), try_remove_lightsnare(), and try_remove_webs().

Referenced by avatar_action::move(), npc::move_to(), and game::vertical_move().

◆ movement_mode_is()

bool Character::movement_mode_is ( character_movemode  mode) const

Check against the character's current movement mode.

Definition at line 1559 of file character.cpp.

1560{
1561 return move_mode == mode;
1562}

References move_mode.

Referenced by map::build_vision_transparency_cache(), avatar::cycle_move_mode(), draw_health_classic(), avatar_action::move(), move_mode_color(), move_mode_string(), game::on_move_effects(), Creature::sees(), game::vertical_move(), and game::walk_move().

◆ mut_cbm_encumb()

void Character::mut_cbm_encumb ( char_encumbrance_data vals) const
protected

Applies encumbrance from mutations and bionics only.

Definition at line 4045 of file character.cpp.

4046{
4047
4048 for( const bionic_id &bid : get_bionics() ) {
4049 for( const std::pair<const bodypart_str_id, int> &element : bid->encumbrance ) {
4050 vals.elems[element.first->token].encumbrance += element.second;
4051 }
4052 }
4053
4055 for( auto &val : vals.elems ) {
4056 val.encumbrance += 3; // Slight encumbrance to all parts except eyes
4057 }
4058 vals.elems[bp_eyes].encumbrance -= 3;
4059 }
4060
4061 // Lower penalty for bps covered only by XL armor
4062 const auto oversize = exclusive_flag_coverage( flag_OVERSIZE );
4063 for( const trait_id &mut : get_mutations() ) {
4064 apply_mut_encumbrance( vals, mut, oversize );
4065 }
4066}
static const bionic_id bio_shock_absorber("bio_shock_absorber")
static void apply_mut_encumbrance(char_encumbrance_data &vals, const trait_id &mut, const body_part_set &oversize)
Definition: character.cpp:4030

References apply_mut_encumbrance(), bio_shock_absorber, bp_eyes, char_encumbrance_data::elems, exclusive_flag_coverage(), flag_OVERSIZE(), get_bionics(), get_mutations(), and has_active_bionic().

Referenced by calc_encumbrance().

◆ mutate()

void Character::mutate ( )

Picks a random valid mutation and gives it to the Character, possibly removing/changing others along the way.

Definition at line 820 of file mutation.cpp.

821{
822 if( get_option<bool>( "BALANCED_MUTATIONS" ) ) {
824 if( !mutagen ) {
825 return;
826 }
827 float mut_power = to_turns<float>( mutagen.get_duration() ) / to_turns<float>
828 ( mutagen.get_int_dur_factor() );
829 add_msg_if_player( m_debug, "Mutation accumulation: %.1f", mut_power );
830 while( mut_power > 1 || roll_remainder( mut_power ) > 0 ) {
831 std::map<trait_id, float> chances = mutation_chances();
832
833 weighted_float_list<trait_id> mutation_picker;
834 for( const auto &p : chances ) {
835 mutation_picker.add( p.first, p.second );
836 }
837
838 for( int tries = 0; tries < 3; tries++ ) {
839 const trait_id *selected = mutation_picker.pick();
840 if( selected == nullptr ) {
841 continue;
842 }
843 add_msg_if_player( m_debug, "Selected mutation %s", selected->obj().name().c_str() );
844 if( has_trait( *selected ) ) {
845 remove_mutation( *selected );
846 break;
847 } else {
848 mutate_towards( *selected );
849 break;
850 }
851 }
852
853 mutagen.mod_duration( -mutagen.get_int_dur_factor() );
854 mut_power -= 1.0f;
855 }
856 } else {
857 old_mutate();
859 }
860}
void remove_mutation(const trait_id &mut, bool silent=false)
Removes a mutation, downgrading to the previous level if possible.
Definition: mutation.cpp:1313
bool mutate_towards(std::vector< trait_id > muts, int num_tries=INT_MAX)
Mutates toward one of the given mutations, upgrading or removing conflicts if necessary.
Definition: mutation.cpp:1072
std::map< trait_id, float > mutation_chances() const
Calculate percentage chances for mutations.
Definition: mutation.cpp:727
void old_mutate()
Definition: mutation.cpp:862
time_duration get_int_dur_factor() const
Returns the number of turns it takes for the intensity to fall by 1 or 0 if intensity isn't based on ...
Definition: effect.cpp:1207
static const efftype_id effect_accumulated_mutagen("accumulated_mutagen")
T * add(const T &obj, const W &weight)
This will add a new object to the weighted list.
Definition: weighted_list.h:33
const T * pick(unsigned int randi) const
This will return a pointer to an object from the list randomly selected and biased by weight.
Definition: weighted_list.h:94

References weighted_list< W, T >::add(), Creature::add_msg_if_player(), effect_accumulated_mutagen, effect::get_duration(), Creature::get_effect(), effect::get_int_dur_factor(), has_trait(), m_debug, effect::mod_duration(), mutate_towards(), mutation_chances(), mutation_branch::name(), old_mutate(), weighted_list< W, T >::pick(), Creature::remove_effect(), remove_mutation(), and roll_remainder().

Referenced by iuse::artifact(), eff_fun_mutating(), hardcoded_effects(), marloss_common(), spell_effect::mutate(), mutate_category(), iuse::mycus(), mattack::science(), iuse::sewage(), suffer_from_artifacts(), suffer_from_other_mutations(), and suffer_from_radiation().

◆ mutate_category()

void Character::mutate_category ( const std::string &  mut_cat)

Picks a random valid mutation in a category and mutate_towards() it.

Definition at line 1019 of file mutation.cpp.

1020{
1021 // Hacky ID comparison is better than separate hardcoded branch used before
1022 // TODO: Turn it into the null id
1023 if( cat == "ANY" ) {
1024 mutate();
1025 return;
1026 }
1027
1028 bool force_bad = one_in( 3 ) && !get_option<bool>( "BALANCED_MUTATIONS" );
1029 bool force_good = false;
1030 if( has_trait( trait_ROBUST ) && force_bad ) {
1031 // Robust Genetics gives you a 33% chance for a good mutation,
1032 // instead of the 33% chance of a bad one.
1033 force_bad = false;
1034 force_good = true;
1035 }
1036 if( has_trait( trait_CHAOTIC_BAD ) ) {
1037 force_bad = true;
1038 force_good = false;
1039 }
1040
1041 // Pull the category's list for valid mutations
1042 std::vector<trait_id> valid = mutations_category[cat];
1043
1044 // Remove anything we already have, that we have a child of, or that
1045 // goes against our intention of a good/bad mutation
1046 for( size_t i = 0; i < valid.size(); i++ ) {
1047 if( !mutation_ok( valid[i], force_good, force_bad ) ) {
1048 valid.erase( valid.begin() + i );
1049 i--;
1050 }
1051 }
1052
1053 mutate_towards( valid, 2 );
1054}
bool mutation_ok(const trait_id &mutation, bool force_good, bool force_bad) const
Returns true if the player doesn't have the mutation or a conflicting one and it complies with the fo...
Definition: mutation.cpp:614
static const trait_id trait_CHAOTIC_BAD("CHAOTIC_BAD")
static const trait_id trait_ROBUST("ROBUST")
std::map< std::string, std::vector< trait_id > > mutations_category

References has_trait(), mutate(), mutate_towards(), mutation_ok(), mutations_category, one_in(), trait_CHAOTIC_BAD, and trait_ROBUST.

Referenced by eff_fun_rat(), hardcoded_effects(), spell_effect::mutate(), iuse::mycus(), npc::randomize(), mutagen_actor::use(), and mutagen_iv_actor::use().

◆ mutate_towards() [1/2]

bool Character::mutate_towards ( const trait_id mut)

Mutates toward the entered mutation, upgrading or removing conflicts if necessary.

Definition at line 1088 of file mutation.cpp.

1089{
1090 if( has_child_flag( mut ) ) {
1091 remove_child_flag( mut );
1092 return true;
1093 }
1094 const mutation_branch &mdata = mut.obj();
1095
1096 bool has_prereqs = false;
1097 bool prereq1 = false;
1098 bool prereq2 = false;
1099 std::vector<trait_id> canceltrait;
1100 std::vector<trait_id> prereq = mdata.prereqs;
1101 std::vector<trait_id> prereqs2 = mdata.prereqs2;
1102 std::vector<trait_id> cancel = mdata.cancels;
1103 std::vector<trait_id> same_type = get_mutations_in_types( mdata.types );
1104 std::vector<trait_id> all_prereqs = get_all_mutation_prereqs( mut );
1105
1106 // Check mutations of the same type - except for the ones we might need for pre-reqs
1107 for( const auto &consider : same_type ) {
1108 if( std::find( all_prereqs.begin(), all_prereqs.end(), consider ) == all_prereqs.end() ) {
1109 cancel.push_back( consider );
1110 }
1111 }
1112
1113 for( size_t i = 0; i < cancel.size(); i++ ) {
1114 if( !has_trait( cancel[i] ) ) {
1115 cancel.erase( cancel.begin() + i );
1116 i--;
1117 } else if( has_base_trait( cancel[i] ) ) {
1118 //If we have the trait, but it's a base trait, don't allow it to be removed normally
1119 canceltrait.push_back( cancel[i] );
1120 cancel.erase( cancel.begin() + i );
1121 i--;
1122 }
1123 }
1124
1125 for( size_t i = 0; i < cancel.size(); i++ ) {
1126 if( !cancel.empty() ) {
1127 trait_id removed = cancel[i];
1128 remove_mutation( removed );
1129 cancel.erase( cancel.begin() + i );
1130 i--;
1131 // This checks for cases where one trait knocks out several others
1132 // Probably a better way, but gets it Fixed Now--KA101
1133 return mutate_towards( mut );
1134 }
1135 }
1136
1137 for( size_t i = 0; ( !prereq1 ) && i < prereq.size(); i++ ) {
1138 if( has_trait( prereq[i] ) ) {
1139 prereq1 = true;
1140 }
1141 }
1142
1143 for( size_t i = 0; ( !prereq2 ) && i < prereqs2.size(); i++ ) {
1144 if( has_trait( prereqs2[i] ) ) {
1145 prereq2 = true;
1146 }
1147 }
1148
1149 if( prereq1 && prereq2 ) {
1150 has_prereqs = true;
1151 }
1152
1153 if( !has_prereqs && ( !prereq.empty() || !prereqs2.empty() ) ) {
1154 if( !prereq1 && !prereq.empty() ) {
1155 return mutate_towards( prereq );
1156 } else if( !prereq2 && !prereqs2.empty() ) {
1157 return mutate_towards( prereqs2 );
1158 }
1159 }
1160
1161 // Check for threshold mutation, if needed
1162 bool threshold = mdata.threshold;
1163 bool profession = mdata.profession;
1164 bool has_threshreq = false;
1165 std::vector<trait_id> threshreq = mdata.threshreq;
1166
1167 // It shouldn't pick a Threshold anyway--they're supposed to be non-Valid
1168 // and aren't categorized. This can happen if someone makes a threshold mutation into a prerequisite.
1169 if( threshold ) {
1170 add_msg_if_player( _( "You feel something straining deep inside you, yearning to be free…" ) );
1171 return false;
1172 }
1173 if( profession ) {
1174 // Profession picks fail silently
1175 return false;
1176 }
1177
1178 for( size_t i = 0; !has_threshreq && i < threshreq.size(); i++ ) {
1179 if( has_trait( threshreq[i] ) ) {
1180 has_threshreq = true;
1181 }
1182 }
1183
1184 // No crossing The Threshold by simply not having it
1185 if( !has_threshreq && !threshreq.empty() ) {
1186 add_msg_if_player( _( "You feel something straining deep inside you, yearning to be free…" ) );
1187 return false;
1188 }
1189
1190 // Check if one of the prerequisites that we have TURNS INTO this one
1191 trait_id replacing = trait_id::NULL_ID();
1192 prereq = mdata.prereqs; // Reset it
1193 for( auto &elem : prereq ) {
1194 if( has_trait( elem ) ) {
1195 const trait_id &pre = elem;
1196 const auto &p = pre.obj();
1197 for( size_t j = 0; !replacing && j < p.replacements.size(); j++ ) {
1198 if( p.replacements[j] == mut ) {
1199 replacing = pre;
1200 }
1201 }
1202 }
1203 }
1204
1205 // Loop through again for prereqs2
1206 trait_id replacing2 = trait_id::NULL_ID();
1207 prereq = mdata.prereqs2; // Reset it
1208 for( auto &elem : prereq ) {
1209 if( has_trait( elem ) ) {
1210 const trait_id &pre2 = elem;
1211 const auto &p = pre2.obj();
1212 for( size_t j = 0; !replacing2 && j < p.replacements.size(); j++ ) {
1213 if( p.replacements[j] == mut ) {
1214 replacing2 = pre2;
1215 }
1216 }
1217 }
1218 }
1219
1220 bool mutation_replaced = false;
1221
1222 game_message_type rating;
1223
1224 if( replacing ) {
1225 const auto &replace_mdata = replacing.obj();
1226 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1227 rating = m_mixed;
1228 } else if( replace_mdata.points - mdata.points < 0 ) {
1229 rating = m_good;
1230 } else if( mdata.points - replace_mdata.points < 0 ) {
1231 rating = m_bad;
1232 } else {
1233 rating = m_neutral;
1234 }
1235 //  TODO: Limit this to visible mutations
1236 // TODO: In case invisible mutation turns into visible or vice versa
1237 // print only the visible mutation appearing/disappearing
1238 add_msg_player_or_npc( rating,
1239 _( "Your %1$s mutation turns into %2$s!" ),
1240 _( "<npcname>'s %1$s mutation turns into %2$s!" ),
1241 replace_mdata.name(), mdata.name() );
1242
1243 g->events().send<event_type::evolves_mutation>( getID(), replace_mdata.id, mdata.id );
1244 unset_mutation( replacing );
1245 mutation_replaced = true;
1246 }
1247 if( replacing2 ) {
1248 const auto &replace_mdata = replacing2.obj();
1249 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1250 rating = m_mixed;
1251 } else if( replace_mdata.points - mdata.points < 0 ) {
1252 rating = m_good;
1253 } else if( mdata.points - replace_mdata.points < 0 ) {
1254 rating = m_bad;
1255 } else {
1256 rating = m_neutral;
1257 }
1258 add_msg_player_or_npc( rating,
1259 _( "Your %1$s mutation turns into %2$s!" ),
1260 _( "<npcname>'s %1$s mutation turns into %2$s!" ),
1261 replace_mdata.name(), mdata.name() );
1262 g->events().send<event_type::evolves_mutation>( getID(), replace_mdata.id, mdata.id );
1263 unset_mutation( replacing2 );
1264 mutation_replaced = true;
1265 }
1266 for( const auto &i : canceltrait ) {
1267 const auto &cancel_mdata = i.obj();
1268 if( mdata.mixed_effect || cancel_mdata.mixed_effect ) {
1269 rating = m_mixed;
1270 } else if( mdata.points < cancel_mdata.points ) {
1271 rating = m_bad;
1272 } else if( mdata.points > cancel_mdata.points ) {
1273 rating = m_good;
1274 } else if( mdata.points == cancel_mdata.points ) {
1275 rating = m_neutral;
1276 } else {
1277 rating = m_mixed;
1278 }
1279 // If this new mutation cancels a base trait, remove it and add the mutation at the same time
1280 add_msg_player_or_npc( rating,
1281 _( "Your innate %1$s trait turns into %2$s!" ),
1282 _( "<npcname>'s innate %1$s trait turns into %2$s!" ),
1283 cancel_mdata.name(), mdata.name() );
1284 g->events().send<event_type::evolves_mutation>( getID(), cancel_mdata.id, mdata.id );
1285 unset_mutation( i );
1286 mutation_replaced = true;
1287 }
1288 if( !mutation_replaced ) {
1289 if( mdata.mixed_effect ) {
1290 rating = m_mixed;
1291 } else if( mdata.points > 0 ) {
1292 rating = m_good;
1293 } else if( mdata.points < 0 ) {
1294 rating = m_bad;
1295 } else {
1296 rating = m_neutral;
1297 }
1298 // TODO: Limit to visible mutations
1299 add_msg_player_or_npc( rating,
1300 _( "You gain a mutation called %s!" ),
1301 _( "<npcname> gains a mutation called %s!" ),
1302 mdata.name() );
1303 g->events().send<event_type::gains_mutation>( getID(), mdata.id );
1304 }
1305
1306 set_mutation( mut );
1307
1310 return true;
1311}
static bool same_type(const std::list< item > &items)
void remove_child_flag(const trait_id &flag)
Removes the mutation's child flag from the player's list.
Definition: mutation.cpp:1471
void drench_mut_calc()
Recalculates mutation drench protection for all bodyparts (ignored/good/neutral stats)
Definition: character.cpp:7816
void set_highest_cat_level()
Recalculates mutation_category_level[] values for the player.
Definition: character.cpp:7793
@ cancel
Definition: craft_command.h:28
game_message_type
Definition: enums.h:259
static std::vector< trait_id > get_all_mutation_prereqs(const trait_id &id)
Definition: mutation.cpp:1056
std::vector< trait_id > get_mutations_in_types(const std::set< std::string > &ids)
trait_id id
Definition: mutation.h:76
bool threshold
Definition: mutation.h:83
std::set< std::string > types
Definition: mutation.h:261
bool profession
Definition: mutation.h:85
std::vector< trait_id > threshreq
Definition: mutation.h:260
bool mixed_effect
Definition: mutation.h:91

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), cancel, mutation_branch::cancels, drench_mut_calc(), evolves_mutation, detail::find(), g, gains_mutation, get_all_mutation_prereqs(), get_mutations_in_types(), getID(), has_base_trait(), has_child_flag(), has_trait(), mutation_branch::id, m_bad, m_good, m_mixed, m_neutral, mutation_branch::mixed_effect, mutate_towards(), mutation_branch::name(), string_id< mutation_branch >::NULL_ID(), string_id< T >::obj(), mutation_branch::points, mutation_branch::prereqs, mutation_branch::prereqs2, mutation_branch::profession, remove_child_flag(), remove_mutation(), same_type(), set_highest_cat_level(), set_mutation(), mutation_branch::threshold, mutation_branch::threshreq, mutation_branch::types, and unset_mutation().

◆ mutate_towards() [2/2]

bool Character::mutate_towards ( std::vector< trait_id muts,
int  num_tries = INT_MAX 
)

Mutates toward one of the given mutations, upgrading or removing conflicts if necessary.

Definition at line 1072 of file mutation.cpp.

1073{
1074 while( !muts.empty() && num_tries > 0 ) {
1075 int i = rng( 0, muts.size() - 1 );
1076
1077 if( mutate_towards( muts[i] ) ) {
1078 return true;
1079 }
1080
1081 muts.erase( muts.begin() + i );
1082 --num_tries;
1083 }
1084
1085 return false;
1086}

References mutate_towards(), and rng().

Referenced by mutate(), spell_effect::mutate(), mutate_category(), mutate_towards(), old_mutate(), and debug_menu::wishmutate().

◆ mutation_armor() [1/3]

resistances Character::mutation_armor ( bodypart_id  bp) const

Returns resistances on a body part provided by mutations.

Definition at line 6427 of file character.cpp.

6428{
6429 resistances res;
6430 for( const trait_id &iter : get_mutations() ) {
6431 res += iter->damage_resistance( bp->token );
6432 }
6433
6434 return res;
6435}

References get_mutations().

Referenced by get_all_armor_type(), get_armor_bash_base(), get_armor_bullet_base(), get_armor_cut_base(), get_armor_type(), mutation_armor(), and passive_absorb_hit().

◆ mutation_armor() [2/3]

float Character::mutation_armor ( bodypart_id  bp,
const damage_unit du 
) const

Definition at line 6442 of file character.cpp.

6443{
6444 return mutation_armor( bp ).get_effective_resist( du );
6445}
float get_effective_resist(const damage_unit &du) const
Definition: damage.cpp:217

References resistances::get_effective_resist(), and mutation_armor().

◆ mutation_armor() [3/3]

float Character::mutation_armor ( bodypart_id  bp,
damage_type  dt 
) const

Definition at line 6437 of file character.cpp.

6438{
6439 return mutation_armor( bp ).type_resist( dt );
6440}
float type_resist(damage_type dt) const
Definition: damage.cpp:213

References mutation_armor(), and resistances::type_resist().

◆ mutation_attacks()

std::vector< special_attack > Character::mutation_attacks ( Creature t) const

Returns a vector of valid mutation attacks.

Unarmed increases chance of attacking with mutated body parts Dexterity increases chance of attacking with mutated body parts

Definition at line 2020 of file melee.cpp.

2021{
2022 std::vector<special_attack> ret;
2023
2024 std::string target = t.disp_name();
2025
2026 const body_part_set usable_body_parts = exclusive_flag_coverage( "ALLOWS_NATURAL_ATTACKS" );
2027 const int unarmed = get_skill_level( skill_unarmed );
2028
2029 for( const trait_id &pr : get_mutations() ) {
2030 const mutation_branch &branch = pr.obj();
2031 for( const mut_attack &mut_atk : branch.attacks_granted ) {
2032 // Covered body part
2033 if( mut_atk.bp != num_bp && !usable_body_parts.test( mut_atk.bp ) ) {
2034 continue;
2035 }
2036
2037 /** @EFFECT_UNARMED increases chance of attacking with mutated body parts */
2038 /** @EFFECT_DEX increases chance of attacking with mutated body parts */
2039
2040 // Calculate actor ability value to be compared against mutation attack difficulty and add debug message
2041 const int proc_value = get_dex() + unarmed;
2042 add_msg( m_debug, "%s proc chance: %d in %d", pr.c_str(), proc_value, mut_atk.chance );
2043 // If the mutation attack fails to proc, bail out
2044 if( !x_in_y( proc_value, mut_atk.chance ) ) {
2045 continue;
2046 }
2047
2048 // If player has any blocker, bail out
2049 if( std::any_of( mut_atk.blocker_mutations.begin(), mut_atk.blocker_mutations.end(),
2050 [this]( const trait_id & blocker ) {
2051 return has_trait( blocker );
2052 } ) ) {
2053 add_msg( m_debug, "%s not procing: blocked", pr.c_str() );
2054 continue;
2055 }
2056
2057 // Player must have all needed traits
2058 if( !std::all_of( mut_atk.required_mutations.begin(), mut_atk.required_mutations.end(),
2059 [this]( const trait_id & need ) {
2060 return has_trait( need );
2061 } ) ) {
2062 add_msg( m_debug, "%s not procing: unmet req", pr.c_str() );
2063 continue;
2064 }
2065
2066 special_attack tmp;
2067 // Ugly special case: player's strings have only 1 variable, NPC have 2
2068 // Can't use <npcname> here
2069 // TODO: Fix
2070 if( is_player() ) {
2071 tmp.text = string_format( _( mut_atk.attack_text_u ), target );
2072 } else {
2073 tmp.text = string_format( _( mut_atk.attack_text_npc ), name, target );
2074 }
2075
2076 // Attack starts here
2077 if( mut_atk.hardcoded_effect ) {
2078 tmp.damage = hardcoded_mutation_attack( *this, pr );
2079 } else {
2080 damage_instance dam = mut_atk.base_damage;
2081 damage_instance scaled = mut_atk.strength_damage;
2082 scaled.mult_damage( std::min<float>( 15.0f, get_str() ), true );
2083 dam.add( scaled );
2084
2085 tmp.damage = dam;
2086 }
2087
2088 if( tmp.damage.total_damage() > 0.0f ) {
2089 ret.emplace_back( tmp );
2090 } else {
2091 add_msg( m_debug, "%s not procing: zero damage", pr.c_str() );
2092 }
2093 }
2094 }
2095
2096 return ret;
2097}
static damage_instance hardcoded_mutation_attack(const Character &u, const trait_id &id)
Definition: melee.cpp:1965
float total_damage() const
Definition: damage.cpp:75
void add(const damage_instance &added_di)
Definition: damage.cpp:93
std::string attack_text_u
Text printed when the attack is proced by you.
Definition: mutation.h:39
std::set< trait_id > blocker_mutations
Need none of those to qualify for this attack.
Definition: mutation.h:45
std::set< trait_id > required_mutations
Need all of those to qualify for this attack.
Definition: mutation.h:43
int chance
Chance to proc is one_in( chance - dex - unarmed )
Definition: mutation.h:51
body_part bp
If not num_bp, this body part needs to be uncovered for the attack to proc.
Definition: mutation.h:48
damage_instance base_damage
Definition: mutation.h:53
bool hardcoded_effect
Should be true when and only when this attack needs hardcoded handling.
Definition: mutation.h:58
damage_instance strength_damage
Multiplied by strength and added to the above.
Definition: mutation.h:55
std::string attack_text_npc
As above, but for npc.
Definition: mutation.h:41
std::vector< mut_attack > attacks_granted
Attacks granted by this mutation.
Definition: mutation.h:250
std::string text
Definition: character.h:197
damage_instance damage
Definition: character.h:198

References _, damage_instance::add(), add_msg(), mut_attack::attack_text_npc, mut_attack::attack_text_u, mutation_branch::attacks_granted, mut_attack::base_damage, mut_attack::blocker_mutations, mut_attack::bp, mut_attack::chance, special_attack::damage, Creature::disp_name(), exclusive_flag_coverage(), get_dex(), get_mutations(), get_skill_level(), get_str(), mut_attack::hardcoded_effect, hardcoded_mutation_attack(), Creature::is_player(), m_debug, damage_instance::mult_damage(), name, num_bp, mut_attack::required_mutations, cata::hash64_detail::ret, skill_unarmed, mut_attack::strength_damage, string_format(), body_part_set::test(), special_attack::text, damage_instance::total_damage(), and x_in_y().

Referenced by perform_special_attacks().

◆ mutation_chances()

std::map< trait_id, float > Character::mutation_chances ( ) const

Calculate percentage chances for mutations.

Definition at line 727 of file mutation.cpp.

728{
729 bool force_bad = false;
730 const bool force_good = false;
732 force_bad = true;
733 }
734
735 int current_score = genetic_score( *this );
736 // 10/10/10/10 in stats, balanced traits, plus tip
737 int expected_score = 4 * 10 + 6;
738 int direction = expected_score - current_score;
739
740 // Duplicates allowed - they'll increase chances of change
741 std::vector<potential_mutation> potential;
742
743 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
744 const trait_id &base_mutation = traits_iter.id;
745 const mutation_branch &base_mdata = traits_iter;
746 bool thresh_save = base_mdata.threshold;
747 bool prof_save = base_mdata.profession;
748 bool purify_save = !base_mdata.purifiable;
749 bool can_remove = !thresh_save && !prof_save && !purify_save;
750
751 if( has_trait( base_mutation ) ) {
752 for( const trait_id &mutation : base_mdata.replacements ) {
753 if( mutation->valid && mutation_ok( mutation, force_good, force_bad ) ) {
754 potential.emplace_back( base_mutation, mutation, 3 );
755 }
756 }
757
758 for( const trait_id &mutation : base_mdata.additions ) {
759 if( mutation->valid && mutation_ok( mutation, force_good, force_bad ) ) {
760 potential.emplace_back( trait_id::NULL_ID(), mutation, 3 );
761 }
762 }
763
764 // Removal or downgrade (if possible)
765 if( can_remove ) {
766 potential.emplace_back( base_mutation, trait_id::NULL_ID(), 2 );
767 }
768 } else {
769 // Addition from nothing
770 // Duplicates addition above, but that's OK, we need to handle dupes anyway
771 if( base_mutation->valid && mutation_ok( base_mutation, force_good, force_bad ) ) {
772 potential.emplace_back( trait_id::NULL_ID(), base_mutation, 1 );
773 }
774 }
775 }
776
777 // We need all mutation categories in here
778 std::map<std::string, int> padded_mut_cat_lvl = mutation_category_level;
779 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
780 for( const std::string &cat : traits_iter.category ) {
781 // Will do nothing if it exists already
782 padded_mut_cat_lvl.insert( std::make_pair( cat, 0 ) );
783 }
784 }
785
786 const std::map<std::string, float> add_weighs =
787 calc_category_weights( padded_mut_cat_lvl, true );
788 const std::map<std::string, float> rem_weighs =
789 calc_category_weights( padded_mut_cat_lvl, false );
790
791 // Not normalized
792 std::map<trait_id, float> chances;
793
794 // Warning: has duplicates
795 for( const potential_mutation &pm : potential ) {
796 int cost_from = pm.from.is_valid() ? pm.from->cost : 0;
797 int cost_to = pm.to.is_valid() ? pm.to->cost : 0;
798 int score_diff = cost_to - cost_from;
799
800 if( pm.to.is_valid() ) {
801 float cat_mod = std::accumulate( pm.to->category.begin(), pm.to->category.end(), 0.0f,
802 [&add_weighs]( float m, const std::string & cat ) {
803 return std::max( m, add_weighs.at( cat ) );
804 } );
805 float c = score_difference_to_chance( direction + score_diff );
806 chances[pm.to] += c * cat_mod;
807 } else if( pm.from.is_valid() ) {
808 float cat_mod = std::accumulate( pm.from->category.begin(), pm.from->category.end(), 0.0f,
809 [&rem_weighs]( float m, const std::string & cat ) {
810 return std::min( m, rem_weighs.at( cat ) );
811 } );
812 float c = score_difference_to_chance( direction - score_diff );
813 chances[pm.from] += c * cat_mod;
814 }
815 }
816
817 return normalized_map( chances );
818}
direction
Definition: line.h:39
constexpr double c
Definition: magic.cpp:1032
static float score_difference_to_chance(float diff)
Definition: mutation.cpp:665
static T normalized_map(const T &ctn)
Definition: mutation.cpp:674
static int genetic_score(const Character &c)
Definition: mutation.cpp:658
static std::map< std::string, float > calc_category_weights(const std::map< std::string, int > &mcl, bool addition)
Definition: mutation.cpp:694
static const std::vector< mutation_branch > & get_all()
All known mutations.
bool purifiable
Definition: mutation.h:81
std::vector< trait_id > additions
Definition: mutation.h:264

References mutation_branch::additions, c, calc_category_weights(), genetic_score(), mutation_branch::get_all(), has_trait(), string_id< T >::id(), mutation_category_level, mutation_ok(), normalized_map(), string_id< mutation_branch >::NULL_ID(), mutation_branch::profession, mutation_branch::purifiable, mutation_branch::replacements, score_difference_to_chance(), mutation_branch::threshold, trait_CHAOTIC_BAD, and mutation_branch::valid.

Referenced by debug_menu::debug(), and mutate().

◆ mutation_effect()

void Character::mutation_effect ( const trait_id mut)

Handles things like removal of armor, etc.

Definition at line 256 of file mutation.cpp.

257{
258 if( mut == trait_GLASSJAW ) {
259 recalc_hp();
260
261 } else if( mut == trait_STR_ALPHA ) {
262 if( str_max < 16 ) {
263 str_max = 8 + str_max / 2;
264 }
265 apply_mods( mut, true );
266 recalc_hp();
267 } else if( mut == trait_DEX_ALPHA ) {
268 if( dex_max < 16 ) {
269 dex_max = 8 + dex_max / 2;
270 }
271 apply_mods( mut, true );
272 } else if( mut == trait_INT_ALPHA ) {
273 if( int_max < 16 ) {
274 int_max = 8 + int_max / 2;
275 }
276 apply_mods( mut, true );
277 } else if( mut == trait_INT_SLIME ) {
278 int_max *= 2; // Now, can you keep it? :-)
279
280 } else if( mut == trait_PER_ALPHA ) {
281 if( per_max < 16 ) {
282 per_max = 8 + per_max / 2;
283 }
284 apply_mods( mut, true );
285 } else {
286 apply_mods( mut, true );
287 }
288
290
291 const auto &branch = mut.obj();
292 if( branch.hp_modifier != 0.0f || branch.hp_modifier_secondary != 0.0f ||
293 branch.hp_adjustment != 0.0f ) {
294 recalc_hp();
295 }
296
297 remove_worn_items_with( [&]( item & armor ) {
298 static const std::string mutation_safe = "OVERSIZE";
299 if( armor.has_flag( mutation_safe ) ) {
300 return false;
301 }
302 if( !branch.conflicts_with_item( armor ) ) {
303 return false;
304 }
305
307 _( "Your %s is pushed off!" ),
308 _( "<npcname>'s %s is pushed off!" ),
309 armor.tname() );
310 get_map().add_item_or_charges( pos(), armor );
311 return true;
312 } );
313
314 if( branch.starts_active ) {
315 my_mutations[mut].powered = true;
316 }
317
318 on_mutation_gain( mut );
319}
std::list< item > remove_worn_items_with(std::function< bool(item &)> filter)
Similar to remove_items_with, but considers only worn items and not their content (item::contents is ...
Definition: character.cpp:2294
static const trait_id trait_PER_ALPHA("PER_ALPHA")
static const trait_id trait_STR_ALPHA("STR_ALPHA")
static const trait_id trait_GLASSJAW("GLASSJAW")
static const trait_id trait_DEX_ALPHA("DEX_ALPHA")
static const trait_id trait_INT_SLIME("INT_SLIME")
static const trait_id trait_INT_ALPHA("INT_ALPHA")

References _, Creature::add_msg_player_or_npc(), apply_mods(), dex_max, get_map(), item::has_flag(), int_max, m_bad, my_mutations, string_id< T >::obj(), on_mutation_gain(), per_max, pos(), recalc_hp(), recalculate_size(), remove_worn_items_with(), str_max, item::tname(), trait_DEX_ALPHA, trait_GLASSJAW, trait_INT_ALPHA, trait_INT_SLIME, trait_PER_ALPHA, and trait_STR_ALPHA.

Referenced by on_item_wear(), set_mutation(), and switch_mutations().

◆ mutation_loss_effect()

void Character::mutation_loss_effect ( const trait_id mut)

Handles what happens when you lose a mutation.

Definition at line 321 of file mutation.cpp.

322{
323 if( mut == trait_GLASSJAW ) {
324 recalc_hp();
325
326 } else if( mut == trait_STR_ALPHA ) {
327 apply_mods( mut, false );
328 if( str_max < 16 ) {
329 str_max = 2 * ( str_max - 8 );
330 }
331 recalc_hp();
332 } else if( mut == trait_DEX_ALPHA ) {
333 apply_mods( mut, false );
334 if( dex_max < 16 ) {
335 dex_max = 2 * ( dex_max - 8 );
336 }
337 } else if( mut == trait_INT_ALPHA ) {
338 apply_mods( mut, false );
339 if( int_max < 16 ) {
340 int_max = 2 * ( int_max - 8 );
341 }
342 } else if( mut == trait_INT_SLIME ) {
343 int_max /= 2; // In case you have a freak accident with the debug menu ;-)
344
345 } else if( mut == trait_PER_ALPHA ) {
346 apply_mods( mut, false );
347 if( per_max < 16 ) {
348 per_max = 2 * ( per_max - 8 );
349 }
350 } else {
351 apply_mods( mut, false );
352 }
353
355
356 const auto &branch = mut.obj();
357 if( branch.hp_modifier != 0.0f || branch.hp_modifier_secondary != 0.0f ||
358 branch.hp_adjustment != 0.0f ) {
359 recalc_hp();
360 }
361
362 on_mutation_loss( mut );
363}
void on_mutation_loss(const trait_id &mid)
Called when a mutation is lost.
Definition: character.cpp:9903

References apply_mods(), dex_max, int_max, string_id< T >::obj(), on_mutation_loss(), per_max, recalc_hp(), recalculate_size(), str_max, trait_DEX_ALPHA, trait_GLASSJAW, trait_INT_ALPHA, trait_INT_SLIME, trait_PER_ALPHA, and trait_STR_ALPHA.

Referenced by on_item_takeoff(), switch_mutations(), and unset_mutation().

◆ mutation_ok()

bool Character::mutation_ok ( const trait_id mutation,
bool  force_good,
bool  force_bad 
) const

Returns true if the player doesn't have the mutation or a conflicting one and it complies with the force typing.

Definition at line 614 of file mutation.cpp.

615{
616 if( !is_category_allowed( mutation->category ) ) {
617 return false;
618 }
619 if( mutation_branch::trait_is_blacklisted( mutation ) ) {
620 return false;
621 }
622 if( has_trait( mutation ) || has_child_flag( mutation ) ) {
623 // We already have this mutation or something that replaces it.
624 return false;
625 }
626
627 for( const bionic_id &bid : get_bionics() ) {
628 for( const trait_id &mid : bid->canceled_mutations ) {
629 if( mid == mutation ) {
630 return false;
631 }
632 }
633 }
634
635 const mutation_branch &mdata = mutation.obj();
636 if( force_bad && mdata.points > 0 ) {
637 // This is a good mutation, and we're due for a bad one.
638 return false;
639 }
640
641 if( force_good && mdata.points < 0 ) {
642 // This is a bad mutation, and we're due for a good one.
643 return false;
644 }
645
646 return true;
647}
bool is_category_allowed(const std::vector< std::string > &category) const
Returns true if this category of mutation is allowed.
Definition: mutation.cpp:371
std::vector< std::string > category
Definition: mutation.h:265
static bool trait_is_blacklisted(const trait_id &tid)
Check if the trait with the given ID is blacklisted.

References mutation_branch::category, get_bionics(), has_child_flag(), has_trait(), is_category_allowed(), string_id< T >::obj(), mutation_branch::points, and mutation_branch::trait_is_blacklisted().

Referenced by mutate_category(), mutation_chances(), and old_mutate().

◆ mutation_spend_resources()

void Character::mutation_spend_resources ( const trait_id mut)

Removes the appropriate costs (NOTE: will reapply mods & recalc sightlines in case of newly activated mutation).

Definition at line 1698 of file mutation.cpp.

1699{
1700 const mutation_branch &mdata = mut.obj();
1701 char_trait_data &tdata = my_mutations[mut];
1702 int cost = mdata.cost;
1703 if( tdata.powered && tdata.charge > 0 ) {
1704 // Already-on units just lose a bit of charge
1705 tdata.charge--;
1706 } else {
1707 // Not-on units, or those with zero charge, have to pay the power cost
1708 if( mdata.cooldown > 0 ) {
1709 tdata.charge = mdata.cooldown - 1;
1710 }
1711 if( mdata.hunger ) {
1712 // burn some energy
1713 mod_stored_kcal( -cost * 6 );
1714 }
1715 if( mdata.thirst ) {
1716 mod_thirst( cost );
1717 }
1718 if( mdata.fatigue ) {
1719 mod_fatigue( cost );
1720 }
1721
1722 // Handle stat changes from activation
1723 apply_mods( mut, true );
1725 }
1726}
int charge
Time (in turns) until the mutation increase hunger/thirst/fatigue according to its cost (mutation_bra...
Definition: character.h:218

References apply_mods(), char_trait_data::charge, mutation_branch::cooldown, mutation_branch::cost, mutation_branch::fatigue, mutation_branch::hunger, mod_fatigue(), mod_stored_kcal(), mod_thirst(), my_mutations, string_id< T >::obj(), char_trait_data::powered, recalc_sight_limits(), and mutation_branch::thirst.

Referenced by activate_mutation(), iexamine::ledge(), and game::vertical_move().

◆ mutation_value()

float Character::mutation_value ( const std::string &  val) const

Goes over all mutations, gets min and max of a value with given name.

Returns
min( 0, lowest ) + max( 0, highest )

Definition at line 6643 of file character.cpp.

6644{
6645 // Syntax similar to tuple get<n>()
6646 const auto found = mutation_value_map.find( val );
6647
6648 if( found == mutation_value_map.end() ) {
6649 debugmsg( "Invalid mutation value name %s", val );
6650 return 0.0f;
6651 } else {
6652 return found->second( cached_mutations );
6653 }
6654}
static const std::map< std::string, std::function< float(std::vector< const mutation_branch * >)> > mutation_value_map
Definition: character.cpp:6605

References cached_mutations, debugmsg, and mutation_value_map.

Referenced by attack_cost(), calc_needs_rates(), draw_speed_tab(), get_stamina_max(), healing_rate(), healing_rate_medicine(), hearing_ability(), is_immune_effect(), known_magic::mana_regen_rate(), known_magic::max_mana(), mend(), metabolic_rate_base(), overmap_sight_range(), read_speed(), recalc_hp(), recalc_speed_bonus(), regen(), reset_stats(), run_cost(), rust_rate(), swim_speed(), update_stamina(), visibility(), game::walk_move(), and weight_capacity().

◆ natural_attack_restricted_on()

bool Character::natural_attack_restricted_on ( const bodypart_id bp) const

Returns true if the character is wearing something on the entered body_part, ignoring items with the ALLOWS_NATURAL_ATTACKS flag.

Definition at line 1782 of file character.cpp.

1783{
1784 for( const item &i : worn ) {
1785 if( i.covers( bp->token ) && !i.has_flag( "ALLOWS_NATURAL_ATTACKS" ) &&
1786 !i.has_flag( "SEMITANGIBLE" ) &&
1787 !i.has_flag( "PERSONAL" ) && !i.has_flag( "AURA" ) ) {
1788 return true;
1789 }
1790 }
1791 return false;
1792}

References worn.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ nearby()

std::vector< item_location > Character::nearby ( const std::function< bool(const item *, const item *)> &  func,
int  radius = 1 
) const

Returns nearby items which match the provided predicate.

Definition at line 2198 of file character.cpp.

2200{
2201 std::vector<item_location> res;
2202
2203 visit_items( [&]( const item * e, const item * parent ) {
2204 if( func( e, parent ) ) {
2205 res.emplace_back( const_cast<Character &>( *this ), const_cast<item *>( e ) );
2206 }
2207 return VisitResponse::NEXT;
2208 } );
2209
2210 for( const auto &cur : map_selector( pos(), radius ) ) {
2211 cur.visit_items( [&]( const item * e, const item * parent ) {
2212 if( func( e, parent ) ) {
2213 res.emplace_back( cur, const_cast<item *>( e ) );
2214 }
2215 return VisitResponse::NEXT;
2216 } );
2217 }
2218
2219 for( const auto &cur : vehicle_selector( pos(), radius ) ) {
2220 cur.visit_items( [&]( const item * e, const item * parent ) {
2221 if( func( e, parent ) ) {
2222 res.emplace_back( cur, const_cast<item *>( e ) );
2223 }
2224 return VisitResponse::NEXT;
2225 } );
2226 }
2227
2228 return res;
2229}

References NEXT, pos(), and visitable< Character >::visit_items().

Referenced by bandolier_actor::reload(), and npc::within_boundaries_of_camp().

◆ nutrition_for()

int Character::nutrition_for ( const item comest) const

Handles the nutrition value for a comestible.

Definition at line 467 of file consumption.cpp.

468{
470}
static constexpr float kcal_per_nutr
1 nutr ~= 8.7kcal (1 nutr/5min = 288 nutr/day at 2500kcal/day)
Definition: itype.h:180
int kcal
amount of kcal this food has
Definition: stomach.h:18

References compute_effective_nutrients(), nutrients::kcal, and islot_comestible::kcal_per_nutr.

Referenced by iuse::blech(), consume_effects(), npc::decide_needs(), eat(), iuse::plantblech(), and npc::value().

◆ old_mutate()

void Character::old_mutate ( )
private

Definition at line 862 of file mutation.cpp.

863{
864 bool force_bad = one_in( 3 );
865 bool force_good = false;
866 if( has_trait( trait_ROBUST ) && force_bad ) {
867 // Robust Genetics gives you a 33% chance for a good mutation,
868 // instead of the 33% chance of a bad one.
869 force_bad = false;
870 force_good = true;
871 }
873 force_bad = true;
874 force_good = false;
875 }
876
877 // Determine the highest mutation category
878 std::string cat = get_highest_category();
879
880 if( !is_category_allowed( cat ) ) {
881 cat.clear();
882 }
883
884 // See if we should upgrade/extend an existing mutation...
885 std::vector<trait_id> upgrades;
886
887 // ... or remove one that is not in our highest category
888 std::vector<trait_id> downgrades;
889
890 // For each mutation...
891 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
892 const trait_id &base_mutation = traits_iter.id;
893 const mutation_branch &base_mdata = traits_iter;
894 bool thresh_save = base_mdata.threshold;
895 bool prof_save = base_mdata.profession;
896 // are we unpurifiable? (saved from mutating away)
897 bool purify_save = !base_mdata.purifiable;
898
899 // ...that we have...
900 if( has_trait( base_mutation ) ) {
901 // ...consider the mutations that replace it.
902 for( const trait_id &mutation : base_mdata.replacements ) {
903 bool valid_ok = mutation->valid;
904
905 if( ( mutation_ok( mutation, force_good, force_bad ) ) &&
906 ( valid_ok ) ) {
907 upgrades.push_back( mutation );
908 }
909 }
910
911 // ...consider the mutations that add to it.
912 for( const trait_id &mutation : base_mdata.additions ) {
913 bool valid_ok = mutation->valid;
914
915 if( ( mutation_ok( mutation, force_good, force_bad ) ) &&
916 ( valid_ok ) ) {
917 upgrades.push_back( mutation );
918 }
919 }
920
921 // ...consider whether its in our highest category
922 if( has_trait( base_mutation ) && !has_base_trait( base_mutation ) ) {
923 // Starting traits don't count toward categories
924 std::vector<trait_id> group = mutations_category[cat];
925 bool in_cat = false;
926 for( const trait_id &elem : group ) {
927 if( elem == base_mutation ) {
928 in_cat = true;
929 break;
930 }
931 }
932
933 // mark for removal
934 // no removing Thresholds/Professions this way!
935 // unpurifiable traits also cannot be purified
936 if( !in_cat && !thresh_save && !prof_save && !purify_save ) {
937 if( one_in( 4 ) ) {
938 downgrades.push_back( base_mutation );
939 }
940 }
941 }
942 }
943 }
944
945 // Preliminary round to either upgrade or remove existing mutations
946 if( one_in( 2 ) ) {
947 if( !upgrades.empty() ) {
948 // (upgrade count) chances to pick an upgrade, 4 chances to pick something else.
949 size_t roll = rng( 0, upgrades.size() + 4 );
950 if( roll < upgrades.size() ) {
951 // We got a valid upgrade index, so use it and return.
952 mutate_towards( upgrades[roll] );
953 return;
954 }
955 }
956 } else {
957 // Remove existing mutations that don't fit into our category
958 if( !downgrades.empty() && !cat.empty() ) {
959 size_t roll = rng( 0, downgrades.size() + 4 );
960 if( roll < downgrades.size() ) {
961 remove_mutation( downgrades[roll] );
962 return;
963 }
964 }
965 }
966
967 std::vector<trait_id> valid; // Valid mutations
968 bool first_pass = true;
969
970 do {
971 // If we tried once with a non-NULL category, and couldn't find anything valid
972 // there, try again with empty category
973 // CHAOTIC_BAD lets the game pull from any category by default
974 if( !first_pass || has_trait( trait_CHAOTIC_BAD ) ) {
975 cat.clear();
976 }
977
978 if( cat.empty() ) {
979 // Pull the full list
980 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
981 if( traits_iter.valid && is_category_allowed( traits_iter.category ) ) {
982 valid.push_back( traits_iter.id );
983 }
984 }
985 } else {
986 // Pull the category's list
987 valid = mutations_category[cat];
988 }
989
990 // Remove anything we already have, that we have a child of, or that
991 // goes against our intention of a good/bad mutation
992 for( size_t i = 0; i < valid.size(); i++ ) {
993 if( ( !mutation_ok( valid[i], force_good, force_bad ) ) ||
994 ( !valid[i]->valid ) ) {
995 valid.erase( valid.begin() + i );
996 i--;
997 }
998 }
999
1000 if( valid.empty() ) {
1001 // So we won't repeat endlessly
1002 first_pass = false;
1003 }
1004 } while( valid.empty() && !cat.empty() );
1005
1006 if( valid.empty() ) {
1007 // Couldn't find anything at all!
1008 return;
1009 }
1010
1011 if( mutate_towards( random_entry( valid ) ) ) {
1012 return;
1013 } else {
1014 // if mutation failed (errors, post-threshold pick), try again once.
1015 mutate_towards( random_entry( valid ) );
1016 }
1017}
group
Definition: sounds.h:125

References mutation_branch::additions, mutation_branch::get_all(), get_highest_category(), has_base_trait(), has_trait(), string_id< T >::id(), is_category_allowed(), mutate_towards(), mutation_ok(), mutations_category, one_in(), mutation_branch::profession, mutation_branch::purifiable, random_entry(), remove_mutation(), mutation_branch::replacements, rng(), mutation_branch::threshold, trait_CHAOTIC_BAD, trait_ROBUST, and mutation_branch::valid.

Referenced by mutate().

◆ on_damage_of_type()

void Character::on_damage_of_type ( int  adjusted_damage,
damage_type  type,
const bodypart_id bp 
)
overrideprotectedvirtual

Reimplemented from Creature.

Definition at line 4519 of file character.cpp.

4520{
4521 // Electrical damage has a chance to temporarily incapacitate bionics in the damaged body_part.
4522 if( type == DT_ELECTRIC ) {
4523 const time_duration min_disable_time = 10_turns * adjusted_damage;
4524 for( bionic &i : *my_bionics ) {
4525 if( !i.powered ) {
4526 // Unpowered bionics are protected from power surges.
4527 continue;
4528 }
4529 const auto &info = i.info();
4530 if( info.has_flag( STATIC( flag_str_id( "BIONIC_SHOCKPROOF" ) ) )
4531 || info.has_flag( STATIC( flag_str_id( "BIONIC_FAULTY" ) ) ) ) {
4532 continue;
4533 }
4534 const std::map<bodypart_str_id, int> &bodyparts = info.occupied_bodyparts;
4535 if( bodyparts.find( bp.id() ) != bodyparts.end() ) {
4536 const int bp_hp = get_part_hp_cur( bp );
4537 // The chance to incapacitate is as high as 50% if the attack deals damage equal to one third of the body part's current health.
4538 if( x_in_y( adjusted_damage * 3, bp_hp ) && one_in( 2 ) ) {
4539 if( i.incapacitated_time == 0_turns ) {
4540 add_msg_if_player( m_bad, _( "Your %s bionic shorts out!" ), info.name );
4541 }
4542 i.incapacitated_time += rng( min_disable_time, 10 * min_disable_time );
4543 }
4544 }
4545 }
4546 }
4547}
#define STATIC(expr)
The purpose of this macro is to provide a concise syntax for creation of inline literals (std::string...
Definition: make_static.h:24
string_id< json_flag > flag_str_id
Definition: type_id.h:213

References _, Creature::add_msg_if_player(), DT_ELECTRIC, Creature::get_part_hp_cur(), int_id< T >::id(), m_bad, my_bionics, one_in(), rng(), STATIC, type, and x_in_y().

◆ on_dodge()

void Character::on_dodge ( Creature source,
int  difficulty 
)
overridevirtual

This creature just dodged an attack - possibly special/ranged attack - from source.

Players should train dodge, monsters may use some special defenses.

Reimplemented from Creature.

Definition at line 8256 of file character.cpp.

8257{
8258 static const matec_id tec_none( "tec_none" );
8259
8260 // Each avoided hit consumes an available dodge
8261 // When no more available we are likely to fail player::dodge_roll
8262 dodges_left--;
8263
8264 // dodging throws of our aim unless we are either skilled at dodging or using a small weapon
8265 const item &weapon = primary_weapon();
8266 if( is_armed() && weapon.is_gun() ) {
8267 recoil += std::max( weapon.volume() / 250_ml - get_skill_level( skill_dodge ), 0 ) * rng( 0, 100 );
8268 recoil = std::min( MAX_RECOIL, recoil );
8269 }
8270
8271 // Even if we are not to train still call practice to prevent skill rust
8272 difficulty = std::max( difficulty, 0 );
8273 as_player()->practice( skill_dodge, difficulty * 2, difficulty );
8274
8275 martial_arts_data->ma_ondodge_effects( *this );
8276
8277 // For adjacent attackers check for techniques usable upon successful dodge
8278 if( source && square_dist( pos(), source->pos() ) == 1 ) {
8279 matec_id tec = pick_technique( *source, primary_weapon(), false, true, false );
8280
8281 if( tec != tec_none && !is_dead_state() ) {
8282 if( get_stamina() < get_stamina_max() / 3 ) {
8283 add_msg( m_bad, _( "You try to counterattack but you are too exhausted!" ) );
8284 } else {
8285 melee_attack( *source, false, &tec );
8286 }
8287 }
8288 }
8289}

References _, add_msg(), Creature::as_player(), dodges_left, get_skill_level(), get_stamina(), get_stamina_max(), is_armed(), is_dead_state(), item::is_gun(), m_bad, martial_arts_data, MAX_RECOIL, melee_attack(), pick_technique(), Creature::pos(), pos(), practice(), primary_weapon(), recoil, rng(), skill_dodge, square_dist(), tec_none, and item::volume().

Referenced by mattack::grab().

◆ on_effect_int_change()

void Character::on_effect_int_change ( const efftype_id effect_type,
int  intensity,
const bodypart_str_id bp 
)
overridevirtual

Called when effect intensity has been changed.

Reimplemented from Creature.

Definition at line 9882 of file character.cpp.

9884{
9885 // Adrenaline can reduce perceived pain (or increase it when you enter comedown).
9886 // See @ref get_perceived_pain()
9888 // Note that calling this does no harm if it wasn't changed.
9889 on_stat_change( "perceived_pain", get_perceived_pain() );
9890 }
9891
9892 morale->on_effect_int_change( effect_type, intensity, bp );
9893}

References effect_adrenaline, get_perceived_pain(), morale, and on_stat_change().

Referenced by load().

◆ on_hit()

void Character::on_hit ( Creature source,
bodypart_id  bp_hit,
dealt_projectile_attack const *  proj 
)
overridevirtual

This creature just got hit by an attack - possibly special/ranged attack - from source.

Parameters
sourceSource creature, can be nullptr
projSource projectile, can be nullptr Players should train dodge, possibly counter-attack somehow.

Implements Creature.

Definition at line 8296 of file character.cpp.

8298{
8300 if( source == nullptr || proj != nullptr ) {
8301 return;
8302 }
8303
8304 bool u_see = g->u.sees( *this );
8305 units::energy trigger_cost_base = bio_ods->power_trigger;
8306 if( has_active_bionic( bio_ods ) && get_power_level() >= trigger_cost_base * 4 ) {
8307 if( is_player() ) {
8308 add_msg( m_good, _( "Your offensive defense system shocks %s in mid-attack!" ),
8309 source->disp_name() );
8310 } else if( u_see ) {
8311 add_msg( _( "%1$s's offensive defense system shocks %2$s in mid-attack!" ),
8312 disp_name(),
8313 source->disp_name() );
8314 }
8315 int shock = rng( 1, 4 );
8316 mod_power_level( -shock * trigger_cost_base );
8317 damage_instance ods_shock_damage;
8318 ods_shock_damage.add_damage( DT_ELECTRIC, shock * 5 );
8319 // Should hit body part used for attack
8320 source->deal_damage( this, bodypart_id( "torso" ), ods_shock_damage );
8321 }
8322 if( !wearing_something_on( bp_hit ) &&
8324 int spine = rng( 1, has_trait( trait_QUILLS ) ? 20 : 8 );
8325 if( !is_player() ) {
8326 if( u_see ) {
8327 add_msg( _( "%1$s's %2$s puncture %3$s in mid-attack!" ), name,
8328 ( has_trait( trait_QUILLS ) ? _( "quills" ) : _( "spines" ) ),
8329 source->disp_name() );
8330 }
8331 } else {
8332 add_msg( m_good, _( "Your %1$s puncture %2$s in mid-attack!" ),
8333 ( has_trait( trait_QUILLS ) ? _( "quills" ) : _( "spines" ) ),
8334 source->disp_name() );
8335 }
8336 damage_instance spine_damage;
8337 spine_damage.add_damage( DT_STAB, spine );
8338 source->deal_damage( this, bodypart_id( "torso" ), spine_damage );
8339 }
8340 if( ( !( wearing_something_on( bp_hit ) ) ) && ( has_trait( trait_THORNS ) ) &&
8341 ( !( source->has_weapon() ) ) ) {
8342 if( !is_player() ) {
8343 if( u_see ) {
8344 add_msg( _( "%1$s's %2$s scrape %3$s in mid-attack!" ), name,
8345 _( "thorns" ), source->disp_name() );
8346 }
8347 } else {
8348 add_msg( m_good, _( "Your thorns scrape %s in mid-attack!" ), source->disp_name() );
8349 }
8350 int thorn = rng( 1, 4 );
8351 damage_instance thorn_damage;
8352 thorn_damage.add_damage( DT_CUT, thorn );
8353 // In general, critters don't have separate limbs
8354 // so safer to target the torso
8355 source->deal_damage( this, bodypart_id( "torso" ), thorn_damage );
8356 }
8357 if( ( !( wearing_something_on( bp_hit ) ) ) && ( has_trait( trait_CF_HAIR ) ) ) {
8358 if( !is_player() ) {
8359 if( u_see ) {
8360 add_msg( _( "%1$s gets a load of %2$s's %3$s stuck in!" ), source->disp_name(),
8361 name, ( _( "hair" ) ) );
8362 }
8363 } else {
8364 add_msg( m_good, _( "Your hairs detach into %s!" ), source->disp_name() );
8365 }
8366 source->add_effect( effect_stunned, 2_turns );
8367 if( one_in( 3 ) ) { // In the eyes!
8368 source->add_effect( effect_blind, 2_turns );
8369 }
8370 }
8371 if( worn_with_flag( "REQUIRES_BALANCE" ) && !has_effect( effect_downed ) ) {
8372 int rolls = 4;
8373 if( worn_with_flag( "ROLLER_ONE" ) ) {
8374 rolls += 2;
8375 }
8376 if( has_trait( trait_PROF_SKATER ) ) {
8377 rolls--;
8378 }
8379 if( has_trait( trait_DEFT ) ) {
8380 rolls--;
8381 }
8382
8383 if( stability_roll() < dice( rolls, 10 ) ) {
8384 if( !is_player() ) {
8385 if( u_see ) {
8386 add_msg( _( "%1$s loses their balance while being hit!" ), name );
8387 }
8388 } else {
8389 add_msg( m_bad, _( "You lose your balance while being hit!" ) );
8390 }
8391 // This kind of downing is not subject to immunity.
8392 add_effect( effect_downed, 2_turns, num_bp, 0, true );
8393 }
8394 }
8395 enchantment_cache->cast_hit_me( *this, source );
8396}
static const trait_id trait_CF_HAIR("CF_HAIR")
static const trait_id trait_QUILLS("QUILLS")
static const trait_id trait_SPINES("SPINES")
static const bionic_id bio_ods("bio_ods")
static const trait_id trait_THORNS("THORNS")
static const trait_id trait_DEFT("DEFT")
static const trait_id trait_PROF_SKATER("PROF_SKATER")
float stability_roll() const override
Returns value of player's stable footing.
virtual bool has_weapon() const =0

References _, damage_instance::add_damage(), Creature::add_effect(), add_msg(), bio_ods, Creature::check_dead_state(), Creature::deal_damage(), dice(), Creature::disp_name(), disp_name(), DT_CUT, DT_ELECTRIC, DT_STAB, effect_blind, effect_downed, effect_stunned, enchantment_cache, g, get_power_level(), has_active_bionic(), Creature::has_effect(), has_trait(), Creature::has_weapon(), Creature::is_player(), m_bad, m_good, mod_power_level(), name, num_bp, one_in(), bionic_data::power_trigger, rng(), stability_roll(), trait_CF_HAIR, trait_DEFT, trait_PROF_SKATER, trait_QUILLS, trait_SPINES, trait_THORNS, wearing_something_on(), and worn_with_flag().

Referenced by melee_attack().

◆ on_hurt()

void Character::on_hurt ( Creature source,
bool  disturb = true 
)

Handles effects that happen when the player is damaged and aware of the fact.

Definition at line 8694 of file character.cpp.

8695{
8697 ( get_part_hp_cur( bodypart_id( "head" ) ) < 25 ||
8698 get_part_hp_cur( bodypart_id( "torso" ) ) < 15 ) ) {
8699 add_effect( effect_adrenaline, 20_minutes );
8700 }
8701
8702 if( disturb ) {
8704 wake_up();
8705 }
8706 if( !is_npc() && !has_effect( effect_narcosis ) ) {
8707 if( source != nullptr ) {
8708 g->cancel_activity_or_ignore_query( distraction_type::attacked,
8709 string_format( _( "You were attacked by %s!" ),
8710 source->disp_name() ) );
8711 } else {
8712 g->cancel_activity_or_ignore_query( distraction_type::attacked, _( "You were hurt!" ) );
8713 }
8714 }
8715 }
8716}
static const trait_id trait_ADRENALINE("ADRENALINE")

References _, Creature::add_effect(), attacked, Creature::disp_name(), effect_adrenaline, effect_narcosis, effect_sleep, g, Creature::get_part_hp_cur(), Creature::has_effect(), has_trait(), Creature::is_npc(), string_format(), trait_ADRENALINE, and wake_up().

Referenced by apply_damage(), deal_damage(), and hurtall().

◆ on_item_takeoff()

void Character::on_item_takeoff ( const item it)

Called when an item is taken off.

Definition at line 9869 of file character.cpp.

9870{
9871 for( const trait_id &mut : it.mutations_from_wearing( *this ) ) {
9872 mutation_loss_effect( mut );
9875 if( get_stamina() > get_stamina_max() ) {
9877 }
9878 }
9879 morale->on_item_takeoff( it );
9880}
void mutation_loss_effect(const trait_id &mut)
Handles what happens when you lose a mutation.
Definition: mutation.cpp:321
std::vector< trait_id > mutations_from_wearing(const Character &guy) const
Definition: item.cpp:9105

References calc_encumbrance(), get_stamina(), get_stamina_max(), morale, mutation_loss_effect(), item::mutations_from_wearing(), recalc_sight_limits(), and set_stamina().

Referenced by item::on_takeoff().

◆ on_item_wear()

void Character::on_item_wear ( const item it)

Called when an item is worn.

Definition at line 9854 of file character.cpp.

9855{
9856 for( const trait_id &mut : it.mutations_from_wearing( *this ) ) {
9857 mutation_effect( mut );
9860
9861 // If the stamina is higher than the max (Languorous), set it back to max
9862 if( get_stamina() > get_stamina_max() ) {
9864 }
9865 }
9866 morale->on_item_wear( it );
9867}
void mutation_effect(const trait_id &mut)
Handles things like removal of armor, etc.
Definition: mutation.cpp:256

References calc_encumbrance(), get_stamina(), get_stamina_max(), morale, mutation_effect(), item::mutations_from_wearing(), recalc_sight_limits(), and set_stamina().

Referenced by debug_menu::character_edit_menu(), load(), and item::on_wear().

◆ on_mutation_gain()

void Character::on_mutation_gain ( const trait_id mid)

Called when a mutation is gained.

Definition at line 9895 of file character.cpp.

9896{
9897 morale->on_mutation_gain( mid );
9898 magic->on_mutation_gain( mid, *this );
9899 update_type_of_scent( mid );
9900 recalculate_enchantment_cache(); // mutations can have enchantments
9901}

References magic, morale, recalculate_enchantment_cache(), and update_type_of_scent().

Referenced by add_bionic(), known_magic::learn_spell(), load(), and mutation_effect().

◆ on_mutation_loss()

void Character::on_mutation_loss ( const trait_id mid)

Called when a mutation is lost.

Definition at line 9903 of file character.cpp.

9904{
9905 morale->on_mutation_loss( mid );
9906 magic->on_mutation_loss( mid );
9907 update_type_of_scent( mid, false );
9908 recalculate_enchantment_cache(); // mutations can have enchantments
9909}

References magic, morale, recalculate_enchantment_cache(), and update_type_of_scent().

Referenced by mutation_loss_effect().

◆ on_stat_change()

void Character::on_stat_change ( const std::string &  stat,
int  value 
)
overridevirtual

Called when a stat is changed.

Reimplemented from Creature.

Definition at line 9911 of file character.cpp.

9912{
9913 morale->on_stat_change( stat, value );
9914}

References morale.

Referenced by load(), on_effect_int_change(), set_fatigue(), set_pain(), set_painkiller(), and set_thirst().

◆ on_worn_item_transform()

void Character::on_worn_item_transform ( const item old_it,
const item new_it 
)

Called when a worn item is transformed.

Definition at line 9916 of file character.cpp.

9917{
9918 morale->on_worn_item_transform( old_it, new_it );
9919}

References morale.

Referenced by iuse_transform::use().

◆ on_worn_item_washed()

void Character::on_worn_item_washed ( const item it)

Called when an item is washed.

Definition at line 9847 of file character.cpp.

9848{
9849 if( is_worn( it ) ) {
9850 morale->on_worn_item_washed( it );
9851 }
9852}

References is_worn(), and morale.

Referenced by wash_activity_actor::finish().

◆ operator=() [1/2]

Character & Character::operator= ( Character &&  )
protecteddefault

◆ operator=() [2/2]

Character & Character::operator= ( const Character )
delete

◆ overmap_los()

bool Character::overmap_los ( const tripoint_abs_omt omt,
int  sight_points 
)

Returns true if overmap tile is within player line-of-sight.

Definition at line 635 of file character.cpp.

636{
638 const point_rel_omt offset = omt.xy() - ompos.xy();
639 if( offset.x() < -sight_points || offset.x() > sight_points ||
640 offset.y() < -sight_points || offset.y() > sight_points ) {
641 // Outside maximum sight range
642 return false;
643 }
644
645 // TODO: fix point types
646 const std::vector<tripoint> line = line_to( ompos.raw(), omt.raw(), 0, 0 );
647 for( size_t i = 0; i < line.size() && sight_points >= 0; i++ ) {
648 const tripoint &pt = line[i];
649 const oter_id &ter = overmap_buffer.ter( tripoint_abs_omt( pt ) );
650 sight_points -= static_cast<int>( ter->get_see_cost() );
651 if( sight_points < 0 ) {
652 return false;
653 }
654 }
655 return true;
656}
constexpr auto & x()
Definition: coordinates.h:118
constexpr Point & raw()
Definition: coordinates.h:111
constexpr auto & y()
Definition: coordinates.h:124
constexpr auto xy() const
Definition: coordinates.h:130
std::vector< coords::coord_point< Point, Origin, Scale > > line_to(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:548
constexpr scale omt
Definition: coordinates.h:32
unsigned char get_see_cost() const
Definition: omdata.h:230

References oter_t::get_see_cost(), global_omt_location(), line(), line_to(), coords::omt, overmap_buffer, coords::coord_point< Point, Origin, Scale >::raw(), overmapbuffer::ter(), coords::coord_point< Point, Origin, Scale >::x(), coords::coord_point< Point, Origin, Scale >::xy(), and coords::coord_point< Point, Origin, Scale >::y().

Referenced by overmap_ui::draw_ascii(), overmap_ui::draw_om_sidebar(), and overmap_ui::draw_overmap_chunk().

◆ overmap_sight_range()

int Character::overmap_sight_range ( int  light_level) const

Returns the distance the player can see on the overmap.

Definition at line 658 of file character.cpp.

659{
660 int sight = sight_range( light_level );
661 if( sight < SEEX ) {
662 return 0;
663 }
664 if( sight <= SEEX * 4 ) {
665 return ( sight / ( SEEX / 2 ) );
666 }
667
668 sight = 6;
669 // The higher your perception, the farther you can see.
670 sight += static_cast<int>( get_per() / 2 );
671 // The higher up you are, the farther you can see.
672 sight += std::max( 0, posz() ) * 2;
673 // Mutations like Scout and Topographagnosia affect how far you can see.
674 sight += mutation_value( "overmap_sight" );
675
676 float multiplier = mutation_value( "overmap_multiplier" );
677 // Binoculars double your sight range.
678 const bool has_optic = ( has_item_with_flag( "ZOOM" ) || has_bionic( bio_eye_optic ) ||
679 ( is_mounted() &&
680 mounted_creature->has_flag( MF_MECH_RECON_VISION ) ) );
681 if( has_optic ) {
682 multiplier += 1;
683 }
684
685 sight = std::round( sight * multiplier );
686 return std::max( sight, 3 );
687}
static const bionic_id bio_eye_optic("bio_eye_optic")
int sight_range(int light_level) const override
Returns the player's sight range.
Definition: character.cpp:606
static constexpr int SEEX
@ MF_MECH_RECON_VISION
Definition: mtype.h:117

References bio_eye_optic, get_per(), has_bionic(), has_item_with_flag(), is_mounted(), MF_MECH_RECON_VISION, mounted_creature, mutation_value(), posz(), SEEX, and sight_range().

Referenced by overmap_ui::draw_ascii(), overmap_ui::draw_om_sidebar(), overmap_ui::draw_overmap_chunk(), and game::update_overmap_seen().

◆ passive_absorb_hit()

void Character::passive_absorb_hit ( const bodypart_id bp,
damage_unit du 
) const

Check for relevant passive, non-clothing that can absorb damage, and reduce by specified damage unit.

Only flat bonuses are checked here. Multiplicative ones are checked in player::absorb_hit. The damage amount will never be reduced to less than 0. This is called from player::absorb_hit

Definition at line 7914 of file character.cpp.

7915{
7916 // >0 check because some mutations provide negative armor
7917 // Thin skin check goes before subdermal armor plates because SUBdermal
7918 if( du.amount > 0.0f ) {
7919 // HACK: Get rid of this as soon as CUT and STAB are split
7920 if( du.type == DT_STAB ) {
7921 damage_unit du_copy = du;
7922 du_copy.type = DT_CUT;
7923 du.amount -= mutation_armor( bp, du_copy );
7924 } else {
7925 du.amount -= mutation_armor( bp, du );
7926 }
7927 }
7928 du.amount -= bionic_armor_bonus( bp, du.type ); //Check for passive armor bionics
7929 du.amount -= mabuff_armor_bonus( du.type );
7930 du.amount = std::max( 0.0f, du.amount );
7931}
int mabuff_armor_bonus(damage_type type) const
Returns the armor bonus against given type from martial arts buffs.
float bionic_armor_bonus(const bodypart_id &bp, damage_type dt) const
Check for passive bionics that provide armor, and returns the armor bonus This is called from player:...
Definition: character.cpp:8221

References damage_unit::amount, bionic_armor_bonus(), DT_CUT, DT_STAB, mabuff_armor_bonus(), mutation_armor(), and damage_unit::type.

Referenced by absorb_hit(), and character_funcs::is_bp_immune_to().

◆ passive_power_gen()

void Character::passive_power_gen ( bionic bio)

Passively produce power from PERPETUAL fuel.

Definition at line 1356 of file bionics.cpp.

1357{
1358 const float passive_fuel_efficiency = bio.info().passive_fuel_efficiency;
1359 if( bio.info().fuel_opts.empty() || bio.is_this_fuel_powered( fuel_type_muscle ) ||
1360 passive_fuel_efficiency == 0.0 ) {
1361 return;
1362 }
1363 const float effective_passive_efficiency = get_effective_efficiency( bio, passive_fuel_efficiency );
1364 const std::vector<itype_id> &fuel_available = get_fuel_available( bio.id );
1365 map &here = get_map();
1366
1367 for( const itype_id &fuel : fuel_available ) {
1368 const item &tmp_fuel = item( fuel );
1369 const int fuel_energy = tmp_fuel.fuel_energy();
1370 if( !tmp_fuel.has_flag( flag_PERPETUAL ) ) {
1371 continue;
1372 }
1373
1374 if( fuel == fuel_type_sun_light ) {
1375 const double modifier = g->natural_light_level( pos().z ) / default_daylight_level();
1376 mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * effective_passive_efficiency );
1377 } else if( fuel == fuel_type_wind ) {
1378 int vehwindspeed = 0;
1379 const optional_vpart_position vp = here.veh_at( pos() );
1380 if( vp ) {
1381 // vehicle velocity in mph
1382 vehwindspeed = std::abs( vp->vehicle().velocity / 100 );
1383 }
1385 const double windpower = get_local_windpower( weather.windspeed + vehwindspeed,
1386 overmap_buffer.ter( global_omt_location() ), pos(), weather.winddirection,
1387 g->is_sheltered( pos() ) );
1388 mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * effective_passive_efficiency );
1389 } else {
1390 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_passive_efficiency );
1391 }
1392
1393 heat_emission( bio, fuel_energy );
1394 if( bio.info().power_gen_emission ) {
1395 here.emit_field( pos(), bio.info().power_gen_emission );
1396 }
1397 }
1398}
float passive_fuel_efficiency
Fraction of fuel energy passively converted to bionic power.
Definition: bionics.h:75

References default_daylight_level(), map::emit_field(), flag_PERPETUAL(), units::from_kilojoule(), item::fuel_energy(), bionic_data::fuel_opts, fuel_type_muscle, fuel_type_sun_light, fuel_type_wind, g, get_effective_efficiency(), get_fuel_available(), get_local_windpower(), get_map(), get_weather(), global_omt_location(), item::has_flag(), heat_emission(), bionic::id, bionic::info(), bionic::is_this_fuel_powered(), mod_power_level(), overmap_buffer, bionic_data::passive_fuel_efficiency, pos(), bionic_data::power_gen_emission, overmapbuffer::ter(), and map::veh_at().

Referenced by process_bionic().

◆ perform_install()

void Character::perform_install ( bionic_id  bid,
bionic_id  upbid,
int  difficulty,
int  success,
int  pl_skill,
const std::string &  installer_name,
const std::vector< trait_id > &  trait_to_rem 
)

Success or failure of installation happens here.

Definition at line 2394 of file bionics.cpp.

2397{
2398
2399 g->events().send<event_type::installs_cbm>( getID(), bid );
2400 if( upbid != bionic_id( "" ) ) {
2401 remove_bionic( upbid );
2402 //~ %1$s - name of the bionic to be upgraded (inferior), %2$s - name of the upgraded bionic (superior).
2403 add_msg( m_good, _( "Upgraded %1$s to %2$s." ),
2404 upbid.obj().name, bid.obj().name );
2405 } else {
2406 //~ %s - name of the bionic.
2407 add_msg( m_good, _( "Installed %s." ), bid.obj().name );
2408 }
2409
2410 add_bionic( bid );
2411
2412 if( !trait_to_rem.empty() ) {
2413 for( const trait_id &tid : trait_to_rem ) {
2414 if( has_trait( tid ) ) {
2415 remove_mutation( tid );
2416 }
2417 }
2418 }
2419 if( success <= 0 ) {
2420 g->events().send<event_type::fails_to_install_cbm>( getID(), bid );
2421
2422 // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30
2423 float adjusted_skill = static_cast<float>( pl_skill ) - std::min( static_cast<float>( 40 ),
2424 static_cast<float>( pl_skill ) - static_cast<float>( pl_skill ) / static_cast<float>
2425 ( 10.0 ) );
2426 bionics_install_failure( installer_name, difficulty, success, adjusted_skill );
2427 }
2428 get_map().invalidate_map_cache( g->get_levz() );
2429}
void remove_bionic(const bionic_id &b)
Removes a bionic from my_bionics[].
Definition: bionics.cpp:2657
void bionics_install_failure(const std::string &installer, int difficulty, int success, float adjusted_skill)
Definition: bionics.cpp:2471
void invalidate_map_cache(const int zlev)
Definition: map.cpp:8969
@ fails_to_install_cbm

References _, add_bionic(), add_msg(), bionic_id, bionics_install_failure(), fails_to_install_cbm, g, get_map(), getID(), has_trait(), installs_cbm, map::invalidate_map_cache(), m_good, bionic_data::name, string_id< T >::obj(), remove_bionic(), remove_mutation(), and behavior::success.

Referenced by install_bionics(), and activity_handlers::operation_do_turn().

◆ perform_special_attacks()

void Character::perform_special_attacks ( Creature t,
dealt_damage_instance dealt_dam 
)

Performs special attacks and their effects (poisonous, stinger, etc.)

Definition at line 1848 of file melee.cpp.

1849{
1850 std::vector<special_attack> special_attacks = mutation_attacks( t );
1851
1852 bool practiced = false;
1853 for( const auto &att : special_attacks ) {
1854 if( t.is_dead_state() ) {
1855 break;
1856 }
1857
1858 // TODO: Make this hit roll use unarmed skill, not weapon skill + weapon to_hit
1859 int hit_spread = t.deal_melee_attack( this, hit_roll() * 0.8 );
1860 if( hit_spread >= 0 ) {
1861 t.deal_melee_hit( this, hit_spread, false, att.damage, dealt_dam );
1862 if( !practiced ) {
1863 // Practice unarmed, at most once per combo
1864 practiced = true;
1865 as_player()->practice( skill_unarmed, rng( 0, 10 ) );
1866 }
1867 }
1868 int dam = dealt_dam.total_damage();
1869 if( dam > 0 ) {
1870 player_hit_message( this, att.text, t, dam );
1871 }
1872 }
1873}
std::vector< special_attack > mutation_attacks(Creature &t) const
Returns a vector of valid mutation attacks.
Definition: melee.cpp:2020

References Creature::as_player(), Creature::deal_melee_attack(), Creature::deal_melee_hit(), hit_roll(), Creature::is_dead_state(), mutation_attacks(), player_hit_message(), practice(), rng(), skill_unarmed, and dealt_damage_instance::total_damage().

Referenced by melee_attack().

◆ perform_technique()

void Character::perform_technique ( const ma_technique technique,
Creature t,
damage_instance di,
int &  move_cost 
)
Intelligence slightly increases chance to learn techniques when using CQB bionic

Definition at line 1426 of file melee.cpp.

1428{
1429 add_msg( m_debug, "dmg before tec:" );
1430 print_damage_info( di );
1431
1432 for( damage_unit &du : di.damage_units ) {
1433 // TODO: Allow techniques to add more damage types to attacks
1434 if( du.amount <= 0 ) {
1435 continue;
1436 }
1437
1438 du.amount += technique.damage_bonus( *this, du.type );
1439 du.damage_multiplier *= technique.damage_multiplier( *this, du.type );
1440 du.res_pen += technique.armor_penetration( *this, du.type );
1441 }
1442
1443 add_msg( m_debug, "dmg after tec:" );
1444 print_damage_info( di );
1445
1446 move_cost *= technique.move_cost_multiplier( *this );
1447 move_cost += technique.move_cost_penalty( *this );
1448
1449 if( technique.down_dur > 0 ) {
1450 t.add_effect( effect_downed, rng( 1_turns, time_duration::from_turns( technique.down_dur ) ) );
1452 if( bash.amount > 0 ) {
1453 bash.amount += 3;
1454 }
1455 }
1456
1457 if( technique.side_switch ) {
1458 const tripoint b = t.pos();
1459 int newx;
1460 int newy;
1461
1462 if( b.x > posx() ) {
1463 newx = posx() - 1;
1464 } else if( b.x < posx() ) {
1465 newx = posx() + 1;
1466 } else {
1467 newx = b.x;
1468 }
1469
1470 if( b.y > posy() ) {
1471 newy = posy() - 1;
1472 } else if( b.y < posy() ) {
1473 newy = posy() + 1;
1474 } else {
1475 newy = b.y;
1476 }
1477
1478 const tripoint &dest = tripoint( newx, newy, b.z );
1479 if( g->is_empty( dest ) ) {
1480 t.setpos( dest );
1481 }
1482 }
1483
1484 if( technique.stun_dur > 0 && !technique.powerful_knockback ) {
1485 t.add_effect( effect_stunned, rng( 1_turns, time_duration::from_turns( technique.stun_dur ) ) );
1486 }
1487
1488 if( technique.knockback_dist ) {
1489 const tripoint prev_pos = t.pos(); // track target startpoint for knockback_follow
1490 const int kb_offset_x = rng( -technique.knockback_spread, technique.knockback_spread );
1491 const int kb_offset_y = rng( -technique.knockback_spread, technique.knockback_spread );
1492 tripoint kb_point( posx() + kb_offset_x, posy() + kb_offset_y, posz() );
1493 for( int dist = rng( 1, technique.knockback_dist ); dist > 0; dist-- ) {
1494 t.knock_back_from( kb_point );
1495 }
1496 // This technique makes the player follow into the tile the target was knocked from
1497 if( technique.knockback_follow ) {
1498 const optional_vpart_position vp0 = g->m.veh_at( pos() );
1499 vehicle *const veh0 = veh_pointer_or_null( vp0 );
1500 bool to_swimmable = g->m.has_flag( "SWIMMABLE", prev_pos );
1501 bool to_deepwater = g->m.has_flag( TFLAG_DEEP_WATER, prev_pos );
1502
1503 // Check if it's possible to move to the new tile
1504 bool move_issue =
1505 g->is_dangerous_tile( prev_pos ) || // Tile contains fire, etc
1506 ( to_swimmable && to_deepwater ) || // Dive into deep water
1507 is_mounted() ||
1508 ( veh0 != nullptr && std::abs( veh0->velocity ) > 100 ) || // Diving from moving vehicle
1509 ( veh0 != nullptr && veh0->player_in_control( g->u ) ) || // Player is driving
1511
1512 if( !move_issue ) {
1513 if( t.pos() != prev_pos ) {
1514 g->place_player( prev_pos );
1515 g->on_move_effects();
1516 }
1517 }
1518 }
1519 }
1520
1521 player *p = dynamic_cast<player *>( &t );
1522
1523 if( technique.take_weapon && !has_weapon() && p != nullptr && p->is_armed() ) {
1524 if( p->is_player() ) {
1525 add_msg_if_npc( _( "<npcname> disarms you and takes your weapon!" ) );
1526 } else {
1527 add_msg_player_or_npc( _( "You disarm %s and take their weapon!" ),
1528 _( "<npcname> disarms %s and takes their weapon!" ),
1529 p->name );
1530 }
1531 item it = p->remove_weapon();
1532 wield( it );
1533 }
1534
1535 if( technique.disarms && p != nullptr && p->is_armed() ) {
1536 g->m.add_item_or_charges( p->pos(), p->remove_weapon() );
1537 if( p->is_player() ) {
1538 add_msg_if_npc( _( "<npcname> disarms you!" ) );
1539 } else {
1540 add_msg_player_or_npc( _( "You disarm %s!" ),
1541 _( "<npcname> disarms %s!" ),
1542 p->name );
1543 }
1544 }
1545
1546 //AOE attacks, feel free to skip over this lump
1547 if( !technique.aoe.empty() ) {
1548 // Remember out moves and stamina
1549 // We don't want to consume them for every attack!
1550 const int temp_moves = moves;
1551 const int temp_stamina = get_stamina();
1552
1553 std::vector<Creature *> targets;
1554
1555 valid_aoe_technique( t, technique, targets );
1556
1557 //hit only one valid target (pierce through doesn't spread out)
1558 if( technique.aoe == "impale" ) {
1559 // TODO: what if targets is empty
1560 Creature *const v = random_entry( targets );
1561 targets.clear();
1562 targets.push_back( v );
1563 }
1564
1565 //hit the targets in the lists (all candidates if wide or burst, or just the unlucky sod if deep)
1566 int count_hit = 0;
1567 for( Creature *const c : targets ) {
1568 melee_attack( *c, false );
1569 }
1570
1571 t.add_msg_if_player( m_good, vgettext( "%d enemy hit!", "%d enemies hit!", count_hit ), count_hit );
1572 // Extra attacks are free of charge (otherwise AoE attacks would SUCK)
1573 moves = temp_moves;
1574 set_stamina( temp_stamina );
1575 }
1576
1577 //player has a very small chance, based on their intelligence, to learn a style whilst using the CQB bionic
1578 if( has_active_bionic( bio_cqb ) && !martial_arts_data->knows_selected_style() ) {
1579 /** @EFFECT_INT slightly increases chance to learn techniques when using CQB bionic */
1580 // Enhanced Memory Banks bionic doubles chance to learn martial art
1581 const int bionic_boost = has_active_bionic( bionic_id( bio_memory ) ) ? 2 : 1;
1582 if( one_in( ( 1400 - ( get_int() * 50 ) ) / bionic_boost ) ) {
1583 martial_arts_data->learn_current_style_CQB( is_player() );
1584 }
1585 }
1586}
bool valid_aoe_technique(Creature &t, const ma_technique &technique)
Check if an area-of-effect technique has valid targets.
Definition: melee.cpp:1277
bool has_weapon() const override
virtual void setpos(const tripoint &pos)=0
void knock_back_from(const tripoint &p)
Definition: creature.cpp:1944
int knockback_dist
Definition: martialarts.h:125
std::string aoe
Definition: martialarts.h:128
float armor_penetration(const Character &u, damage_type type) const
float damage_multiplier(const Character &u, damage_type type) const
bool side_switch
Definition: martialarts.h:116
float damage_bonus(const Character &u, damage_type type) const
float move_cost_multiplier(const Character &u) const
float move_cost_penalty(const Character &u) const
bool take_weapon
Definition: martialarts.h:133
bool knockback_follow
Definition: martialarts.h:129
bool powerful_knockback
Definition: martialarts.h:127
float knockback_spread
Definition: martialarts.h:126
bool player_in_control(const Character &p) const
Definition: vehicle.cpp:278
int velocity
Definition: vehicle.h:1943
static const efftype_id effect_downed("downed")
static const bionic_id bio_memory("bio_memory")
static void print_damage_info(const damage_instance &di)
Definition: melee.cpp:1409
static damage_unit & get_damage_unit(std::vector< damage_unit > &di, const damage_type dt)
Definition: melee.cpp:1397
static const efftype_id effect_stunned("stunned")
static const efftype_id effect_amigara("amigara")
float res_pen
Definition: damage.h:38
vehicle * veh_pointer_or_null(const optional_vpart_position &p)

References _, Creature::add_effect(), add_msg(), Creature::add_msg_if_npc(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), damage_unit::amount, ma_technique::aoe, ma_technique::armor_penetration(), b, spell_effect::bash(), bio_cqb, bio_memory, bionic_id, c, ma_technique::damage_bonus(), damage_unit::damage_multiplier, ma_technique::damage_multiplier(), damage_instance::damage_units, ma_technique::disarms, ma_technique::down_dur, DT_BASH, effect_amigara, effect_downed, effect_stunned, time_duration::from_turns(), g, get_damage_unit(), get_int(), get_stamina(), has_active_bionic(), Creature::has_effect(), has_weapon(), is_armed(), is_mounted(), Creature::is_player(), player::is_player(), Creature::knock_back_from(), ma_technique::knockback_dist, ma_technique::knockback_follow, ma_technique::knockback_spread, m_debug, m_good, martial_arts_data, melee_attack(), move_cost(), ma_technique::move_cost_multiplier(), ma_technique::move_cost_penalty(), Creature::moves, name, one_in(), vehicle::player_in_control(), Creature::pos(), pos(), posx(), posy(), posz(), ma_technique::powerful_knockback, print_damage_info(), random_entry(), remove_weapon(), damage_unit::res_pen, rng(), set_stamina(), Creature::setpos(), ma_technique::side_switch, ma_technique::stun_dur, ma_technique::take_weapon, TFLAG_DEEP_WATER, damage_unit::type, valid_aoe_technique(), veh_pointer_or_null(), vehicle::velocity, vgettext(), and wield().

Referenced by melee_attack().

◆ perform_uninstall()

void Character::perform_uninstall ( bionic_id  bid,
int  difficulty,
int  success,
const units::energy power_lvl,
int  pl_skill 
)

Succes or failure of removal happens here.

Definition at line 2125 of file bionics.cpp.

2127{
2128 map &here = get_map();
2129 if( success > 0 ) {
2130 g->events().send<event_type::removes_cbm>( getID(), bid );
2131
2132 // until bionics can be flagged as non-removable
2133 add_msg_player_or_npc( m_neutral, _( "Your parts are jiggled back into their familiar places." ),
2134 _( "<npcname>'s parts are jiggled back into their familiar places." ) );
2135 add_msg( m_good, _( "Successfully removed %s." ), bid.obj().name );
2136 remove_bionic( bid );
2137
2138 // remove power bank provided by bionic
2139 mod_max_power_level( -power_lvl );
2140
2142 if( bid->itype().is_valid() && !bid.obj().has_flag( flag_BIONIC_FAULTY ) ) {
2143 cbm = item( bid.c_str() );
2144 cbm.faults.emplace( fault_bionic_nonsterile );
2145 }
2146 here.add_item( pos(), cbm );
2147 } else {
2148 g->events().send<event_type::fails_to_remove_cbm>( getID(), bid );
2149 // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30
2150 float adjusted_skill = static_cast<float>( pl_skill ) - std::min( static_cast<float>( 40 ),
2151 static_cast<float>( pl_skill ) - static_cast<float>( pl_skill ) / static_cast<float>
2152 ( 10.0 ) );
2153 bionics_uninstall_failure( difficulty, success, adjusted_skill );
2154
2155 }
2156 here.invalidate_map_cache( g->get_levz() );
2157}
static const flag_str_id flag_BIONIC_FAULTY("BIONIC_FAULTY")
static const fault_id fault_bionic_nonsterile("fault_bionic_nonsterile")
static const itype_id itype_burnt_out_bionic("burnt_out_bionic")
void bionics_uninstall_failure(int difficulty, int success, float adjusted_skill)
When a player fails the surgery.
Definition: bionics.cpp:1812
item & add_item(const tripoint &p, item new_item)
Place an item on the map, despite the parameter name, this is not necessarily a new item.
Definition: map.cpp:4454
@ fails_to_remove_cbm

References _, map::add_item(), add_msg(), Creature::add_msg_player_or_npc(), bionics_uninstall_failure(), string_id< T >::c_str(), fails_to_remove_cbm, fault_bionic_nonsterile, item::faults, flag_BIONIC_FAULTY, g, get_map(), getID(), bionic_data::has_flag(), map::invalidate_map_cache(), string_id< T >::is_valid(), bionic_data::itype(), itype_burnt_out_bionic, m_good, m_neutral, mod_max_power_level(), bionic_data::name, string_id< T >::obj(), pos(), remove_bionic(), removes_cbm, and behavior::success.

Referenced by activity_handlers::operation_do_turn(), and uninstall_bionic().

◆ pick_name()

void Character::pick_name ( bool  bUseDefault = false)

Returns a random name from NAMES_*.

Definition at line 129 of file newcharacter.cpp.

130{
131 if( bUseDefault && !get_option<std::string>( "DEF_CHAR_NAME" ).empty() ) {
132 name = get_option<std::string>( "DEF_CHAR_NAME" );
133 } else {
135 }
136}
std::string generate(bool is_male)
Return a random full name given gender.
Definition: name.cpp:128

References Name::generate(), male, and name.

Referenced by avatar::randomize(), npc::randomize(), and set_description().

◆ pick_technique()

matec_id Character::pick_technique ( Creature t,
const item weap,
bool  crit,
bool  dodge_counter,
bool  block_counter 
)

Returns a random valid technique.

Definition at line 1174 of file melee.cpp.

1176{
1177
1178 const std::vector<matec_id> all = martial_arts_data->get_all_techniques( weap );
1179
1180 std::vector<matec_id> possible;
1181
1182 bool downed = t.has_effect( effect_downed );
1183 bool stunned = t.has_effect( effect_stunned );
1184 bool wall_adjacent = g->m.is_wall_adjacent( pos() );
1185
1186 // first add non-aoe tecs
1187 for( const matec_id &tec_id : all ) {
1188 const ma_technique &tec = tec_id.obj();
1189
1190 // ignore "dummy" techniques like WBLOCK_1
1191 if( tec.dummy ) {
1192 continue;
1193 }
1194
1195 // skip defensive techniques
1196 if( tec.defensive ) {
1197 continue;
1198 }
1199
1200 // skip wall adjacent techniques if not next to a wall
1201 if( tec.wall_adjacent && !wall_adjacent ) {
1202 continue;
1203 }
1204
1205 // skip dodge counter techniques
1206 if( dodge_counter != tec.dodge_counter ) {
1207 continue;
1208 }
1209
1210 // skip block counter techniques
1211 if( block_counter != tec.block_counter ) {
1212 continue;
1213 }
1214
1215 // if critical then select only from critical tecs
1216 // but allow the technique if its crit ok
1217 if( !tec.crit_ok && ( crit != tec.crit_tec ) ) {
1218 continue;
1219 }
1220
1221 // don't apply downing techniques to someone who's already downed
1222 if( downed && tec.down_dur > 0 ) {
1223 continue;
1224 }
1225
1226 // don't apply "downed only" techniques to someone who's not downed
1227 if( !downed && tec.downed_target ) {
1228 continue;
1229 }
1230
1231 // don't apply "stunned only" techniques to someone who's not stunned
1232 if( !stunned && tec.stunned_target ) {
1233 continue;
1234 }
1235
1236 // don't apply disarming techniques to someone without a weapon
1237 // TODO: these are the stat requirements for tec_disarm
1238 // dice( dex_cur + get_skill_level("unarmed"), 8) >
1239 // dice(p->dex_cur + p->get_skill_level("melee"), 10))
1240 if( tec.disarms && !t.has_weapon() ) {
1241 continue;
1242 }
1243
1244 if( ( tec.take_weapon && ( has_weapon() || !t.has_weapon() ) ) ) {
1245 continue;
1246 }
1247
1248 // Don't apply humanoid-only techniques to non-humanoids
1249 if( tec.human_target && !t.in_species( HUMAN ) ) {
1250 continue;
1251 }
1252 // if aoe, check if there are valid targets
1253 if( !tec.aoe.empty() && !valid_aoe_technique( t, tec ) ) {
1254 continue;
1255 }
1256
1257 // If we have negative weighting then roll to see if it's valid this time
1258 if( tec.weighting < 0 && !one_in( std::abs( tec.weighting ) ) ) {
1259 continue;
1260 }
1261
1262 if( tec.is_valid_character( *this ) ) {
1263 possible.push_back( tec.id );
1264
1265 //add weighted options into the list extra times, to increase their chance of being selected
1266 if( tec.weighting > 1 ) {
1267 for( int i = 1; i < tec.weighting; i++ ) {
1268 possible.push_back( tec.id );
1269 }
1270 }
1271 }
1272 }
1273
1274 return random_entry( possible, tec_none );
1275}
virtual bool in_species(const species_id &) const
Definition: creature.cpp:992
bool stunned_target
Definition: martialarts.h:144
bool human_target
Definition: martialarts.h:146
bool block_counter
Definition: martialarts.h:135
bool wall_adjacent
Definition: martialarts.h:145
bool dodge_counter
Definition: martialarts.h:134
bool downed_target
Definition: martialarts.h:143
static const species_id HUMAN("HUMAN")
const std::array< type, 4 > all
For the purposes of iteration.
Definition: om_direction.h:27

References om_direction::all, ma_technique::aoe, ma_technique::block_counter, ma_technique::crit_ok, ma_technique::crit_tec, ma_technique::defensive, ma_technique::disarms, ma_technique::dodge_counter, ma_technique::down_dur, ma_technique::downed_target, ma_technique::dummy, effect_downed, effect_stunned, g, Creature::has_effect(), Creature::has_weapon(), has_weapon(), HUMAN, ma_technique::human_target, ma_technique::id, Creature::in_species(), ma_technique::is_valid_character(), martial_arts_data, one_in(), pos(), random_entry(), ma_technique::stunned_target, ma_technique::take_weapon, tec_none, valid_aoe_technique(), ma_technique::wall_adjacent, and ma_technique::weighting.

Referenced by block_hit(), melee_attack(), and on_dodge().

◆ place_corpse() [1/2]

void Character::place_corpse ( )

Definition at line 10129 of file character.cpp.

10130{
10131 //If the character/NPC is on a distant mission, don't drop their their gear when they die since they still have a local pos
10132 if( !death_drops ) {
10133 return;
10134 }
10135 std::vector<item *> tmp = inv_dump();
10137 map &here = get_map();
10138 for( auto itm : tmp ) {
10139 here.add_item_or_charges( pos(), *itm );
10140 }
10141 for( const bionic &bio : *my_bionics ) {
10142 if( bio.info().itype().is_valid() ) {
10143 item cbm( bio.id.str(), calendar::turn );
10144 cbm.faults.emplace( fault_bionic_nonsterile );
10145 body.components.push_back( cbm );
10146 }
10147 }
10148
10149 // Restore amount of installed pseudo-modules of Power Storage Units
10150 std::pair<int, int> storage_modules = amount_of_storage_bionics();
10151 for( int i = 0; i < storage_modules.first; ++i ) {
10153 cbm.faults.emplace( fault_bionic_nonsterile );
10154 body.components.push_back( cbm );
10155 }
10156 for( int i = 0; i < storage_modules.second; ++i ) {
10158 cbm.faults.emplace( fault_bionic_nonsterile );
10159 body.components.push_back( cbm );
10160 }
10161 here.add_item_or_charges( pos(), body );
10162}
static const itype_id itype_power_storage("bio_power_storage")
static const fault_id fault_bionic_nonsterile("fault_bionic_nonsterile")
static const itype_id itype_power_storage_mkII("bio_power_storage_mkII")
bool death_drops
Definition: character.h:252
std::pair< int, int > amount_of_storage_bionics() const
Returns amount of Storage CBMs in the corpse.
Definition: bionics.cpp:2699
std::map< bodypart_str_id, bodypart > body
this is the actual body of the creature
Definition: creature.h:503
static item make_corpse(const mtype_id &mt=string_id< mtype >::NULL_ID(), time_point turn=calendar::turn, const std::string &name="", int upgrade_time=-1)
Make a corpse of the given monster type.
Definition: item.cpp:510

References map::add_item_or_charges(), amount_of_storage_bionics(), Creature::body, death_drops, fault_bionic_nonsterile, item::faults, get_map(), inv_dump(), itype_power_storage, itype_power_storage_mkII, item::make_corpse(), my_bionics, name, string_id< mtype >::NULL_ID(), pos(), and calendar::turn.

Referenced by npc::die(), game::handle_action(), and game::is_game_over().

◆ place_corpse() [2/2]

void Character::place_corpse ( const tripoint_abs_omt om_target)

Definition at line 10164 of file character.cpp.

10165{
10166 tinymap bay;
10167 bay.load( project_to<coords::sm>( om_target ), false );
10168 point fin{ rng( 1, SEEX * 2 - 2 ), rng( 1, SEEX * 2 - 2 ) };
10169 // This makes no sense at all. It may find a random tile without furniture, but
10170 // if the first try to find one fails, it will go through all tiles of the map
10171 // and essentially select the last one that has no furniture.
10172 // Q: Why check for furniture? (Check for passable or can-place-items seems more useful.)
10173 // Q: Why not grep a random point out of all the possible points (e.g. via random_entry)?
10174 // Q: Why use furn_str_id instead of f_null?
10175 // TODO: fix it, see above.
10176 if( bay.furn( fin ) != furn_str_id( "f_null" ) ) {
10177 for( const tripoint &p : bay.points_on_zlevel() ) {
10178 if( bay.furn( p ) == furn_str_id( "f_null" ) ) {
10179 fin.x = p.x;
10180 fin.y = p.y;
10181 }
10182 }
10183 }
10184
10185 std::vector<item *> tmp = inv_dump();
10187 for( auto itm : tmp ) {
10188 bay.add_item_or_charges( fin, *itm );
10189 }
10190 for( const bionic &bio : *my_bionics ) {
10191 if( bio.info().itype().is_valid() ) {
10192 body.put_in( item( bio.info().itype(), calendar::turn ) );
10193 }
10194 }
10195
10196 // Restore amount of installed pseudo-modules of Power Storage Units
10197 std::pair<int, int> storage_modules = amount_of_storage_bionics();
10198 for( int i = 0; i < storage_modules.first; ++i ) {
10199 body.put_in( item( "bio_power_storage" ) );
10200 }
10201 for( int i = 0; i < storage_modules.second; ++i ) {
10202 body.put_in( item( "bio_power_storage_mkII" ) );
10203 }
10204 bay.add_item_or_charges( fin, body );
10205}
tripoint_range< tripoint > points_on_zlevel() const
Yields a range of all points that are contained in the map and have the z-level of this map (abs_sub)...
Definition: map.cpp:8782
void load(const tripoint &w, bool update_vehicles, bool pump_events=false)
Load submaps into grid.
Definition: map.cpp:6749
Definition: map.h:2065

References map::add_item_or_charges(), amount_of_storage_bionics(), Creature::body, map::furn(), inv_dump(), map::load(), item::make_corpse(), my_bionics, name, string_id< mtype >::NULL_ID(), map::points_on_zlevel(), rng(), SEEX, and calendar::turn.

◆ pos()

const tripoint & Character::pos ( ) const
overridevirtual

Implements Creature.

Definition at line 601 of file character.cpp.

602{
603 return position;
604}

References position.

Referenced by absorb_hit(), iuse::acidbomb_act(), activate_bionic(), npc::activate_item(), activate_mutation(), enchantment::activate_passive(), activity_on_turn_move_loot(), map::add_field(), add_known_trap(), inventory_selector::add_nearby_items(), npc::address_player(), npc::alt_attack(), map::apparent_light_helper(), map::apply_character_light(), apply_persistent_morale(), iuse::artifact(), npc::assess_danger(), assign_activity(), activity_handlers::atm_do_turn(), Creature::auto_find_hostile_target(), game::autopilot_vehicles(), npc::avoid_friendly_fire(), avoid_trap(), iuse::bell(), best_nearby_lifting_assist(), mattack::bio_op_disarm(), blossoms(), iuse::boltcutters(), map::build_vision_transparency_cache(), burn_fuel(), iuse::burrow(), game::butcher(), activity_handlers::butcher_finish(), butchery_drops_harvest(), butchery_quarter(), set_transformed_iuse::bypass(), iuse::cable_attach(), calc_needs_rates(), calculate_aim_cap(), calculate_dispersion(), iuse::call_of_tindalos(), iuse::camera(), player::can_continue_craft(), can_examine_at(), can_hear(), can_mount(), npc::can_move_to(), character_funcs::can_see_fine_details(), iuse_transform::can_use(), firestarter_actor::can_use(), iuse::capture_monster_act(), iexamine::cardreader_foodplace(), enchantment::cast_enchantment_spell(), iexamine::chainfence(), debug_menu::character_edit_menu(), game::chat(), check_art_charge_req(), player::check_eligible_containers_for_crafting(), vehicle::check_heli_ascend(), check_mount_is_spooked(), check_mount_will_move(), npc::check_or_use_weapon_cbm(), check_outbounds_activity(), relic_funcs::check_recharge_reqs(), iuse::chop_tree(), avatar::clear_memorized_tile(), doors::close_door(), game_menus::inv::compare(), complete_construction(), veh_interact::complete_vehicle(), consider_butchery(), consume_charges(), consume_effects(), player::consume_items(), consume_med(), consume_remote_fuel(), player::consume_tools(), game::control_vehicle(), cough(), npc::could_move_onto(), player::craft_consume_tools(), crafting_inventory(), craft_command::create_in_progress_craft(), game::create_starting_npcs(), map::creature_in_field(), game::critter_at(), iuse::crowbar(), iexamine::curtains(), iuse::cut_log_into_planks(), salvage_actor::cut_up(), deactivate_bionic(), deal_damage(), debug_menu::debug(), defer_move(), item_location::impl::item_on_map::describe(), item_location::impl::item_on_vehicle::describe(), trap::detect_trap(), npc::die(), iuse::dig(), iuse::dig_channel(), iuse::directional_antenna(), crafting::disassemble_all(), character_display::disp_info(), game::disp_NPCs(), game::display_scent(), npc::dispose_item(), npc::do_npc_read(), character_funcs::do_pause(), npc::do_pulp(), avatar::do_read(), npc::do_reload(), game::do_turn(), drop_activity_actor::do_turn(), stash_activity_actor::do_turn(), move_items_activity_actor::do_turn(), pickup_activity_actor::do_turn(), throw_activity_actor::do_turn(), iexamine::door_peephole(), game::draw(), draw_bionics_titlebar(), draw_cone_aoe_curses(), draw_env_compact(), draw_health_classic(), anonymous_namespace{animation.cpp}::draw_hit_player_curses(), game::draw_look_around_cursor(), draw_speed_tab(), game::draw_ter(), target_ui::draw_terrain_overlay(), draw_throw_aim(), draw_time_classic(), game::draw_trail_to_square(), draw_veh_compact(), draw_veh_padding(), game::drop(), drop(), drop_invalid_inventory(), npc::drop_items(), talk_function::drop_weapon(), monexamine::dump_items(), eat(), avatar_action::eat_here(), eff_fun_fungus(), eff_fun_hallu(), iuse::einktabletpc(), iexamine::elevator(), emit_radio_signal(), explosion_handler::emp_blast(), npc::enough_time_to_reload(), env_surgery_bonus(), game::examine(), craft_command::execute(), npc::execute_action(), extract_or_wreck_cbms(), npc::faction_display(), iuse::fill_pit(), character_funcs::find_ammo_items_or_mags(), find_auto_consume(), find_best_bench(), npc::find_corpse_to_pulp(), npc::find_dangerous_explosives(), npc::find_item(), activity_handlers::find_mount_do_turn(), game::find_nearby_items(), game::find_or_make_stairs(), find_remote_fuel(), character_funcs::fine_detail_vision_mod(), hacking_activity_actor::finish(), npc::finish_read(), fire(), ranged::fire_gun(), iuse::fishing_rod(), game::fling_creature(), floor_bedding_warmth(), floor_item_warmth(), floor_warmth(), iexamine::flower_marloss(), iexamine::flower_poppy(), activity_handlers::forage_finish(), forced_dismount(), fungal_effects::fungalize(), iuse::fungicide(), mattack::fungus_sprout(), iexamine::fvat_full(), activity_handlers::game_do_turn(), iuse::gasmask(), iexamine::gaspump(), iuse::geiger(), generic_multi_activity_check_requirement(), generic_multi_activity_handler(), generic_multi_activity_locations(), avatar::get_book_reader(), character_funcs::get_crafting_helpers(), game::get_dangerous_tile(), activatable_inventory_preset::get_denial(), get_dodge(), player::get_eligible_containers_for_crafting(), get_heat_radiation(), get_hostile_creatures(), get_item_location(), avatar::get_memorized_tile(), get_next_auto_move_direction(), overmap_ui::get_overmap_path_to(), npc::get_path_avoid(), get_patient(), get_temp(), game::get_veh_dir_indicator_location(), get_visible_creatures(), ranged::get_weapon_dispersion(), talk_function::give_all_aid(), npc::go_to_omt_destination(), npc::good_escape_direction(), grab(), mattack::grab_drag(), game::grabbed_furn_move(), game::grabbed_veh_move(), npc::guard_current_pos(), iuse::gun_repair(), ranged::gunmode_checks_common(), ranged::gunmode_checks_weapon(), iuse::hacksaw(), activity_handlers::hacksaw_finish(), iuse::hammer(), handbrake(), game::handle_action(), target_ui::handle_cursor_movement(), handle_harvest(), handle_melee_wear(), item::handle_pickup_ownership(), npc::handle_sound(), vehicle::handle_trap(), hardcoded_effects(), has_alarm_clock(), has_fire(), has_neighbor(), has_watch(), haul(), npc::heal_player(), npc::heal_self(), heat_emission(), iuse::honeycomb(), i_add_or_drop(), i_rem(), i_rem_keep_contents(), impact(), in_climate_control(), npc_trading::init_buying(), iexamine::intercom(), invoke_item(), npc::is_active(), enchantment::is_active(), place_trap_actor::is_allowed(), is_deaf(), is_driving(), monster::is_fleeing(), game::is_game_over(), game::is_in_viewport(), is_snuggling(), is_solid_neighbor(), ma_requirements::is_valid_character(), is_visible_in_range(), iuse::jackhammer(), monexamine::kill_zslave(), knock_back_to(), game::knockback(), knows_trap(), firestarter_actor::light_mod(), game::list_items(), game::list_monsters(), avatar_funcs::list_potential_theft_witnesses(), vehicle_prototype::load(), game::load(), avatar::load_map_memory(), aim_activity_actor::load_RAS_weapon(), activity_handlers::lockpicking_finish(), activity_handlers::longsalvage_finish(), game::look_around(), npc::look_for_player(), loot(), iuse::lumber(), ranged::make_gun_sound_effect(), activity_handlers::make_zlave_finish(), iuse::makemound(), item_action_generator::map_actions_to_items(), marloss_common(), melee_attack(), melee_special_effects(), avatar::memorize_symbol(), avatar::memorize_tile(), npc::method_of_attack(), mill_activate(), target_handler::mode_turrets(), modify_morale(), game::mon_info_update(), game::monmove(), iuse::mop(), npc::move(), avatar_action::move(), npc::move_away_from(), npc::move_to(), npc::move_to_next(), firestarter_actor::moves_cost_by_fuel(), game::moving_vehicle_dismount(), npc::mug_player(), multicooker_hallu(), mutation_effect(), npc::mutiny(), iuse::mycus(), inventory_selector::naturalize_category(), nearby(), iuse::note_bionics(), npc::npc_dismount(), game::npc_menu(), mattack::nurse_assist(), mattack::nurse_check_up(), mattack::nurse_operate(), item_location::impl::item_on_map::obtain_cost(), item_location::impl::item_on_vehicle::obtain_cost(), on_dodge(), npc::on_load(), item::on_pickup(), item::on_takeoff(), item::on_wear(), open(), map::open_door(), activity_handlers::operation_do_turn(), activity_handlers::operation_finish(), operator_present(), game::overmap_npc_move(), iuse::oxytorch(), activity_handlers::oxytorch_do_turn(), activity_handlers::oxytorch_finish(), passive_power_gen(), iexamine::pay_gas(), game::peek(), perform_technique(), perform_uninstall(), perform_zone_activity_turn(), game::phasing_move(), debug_menu::pick_character(), pick_plant(), character_funcs::pick_safe_adjacent_tile(), pick_technique(), npc::pick_up_item(), iuse::pickaxe(), game::pickup_feet(), iexamine::pit_covered(), place_and_add_as_known(), place_corpse(), npc::place_on_map(), game::place_player(), start_location::place_player(), game::place_player_overmap(), iuse::play_music(), vehicle::player_in_control(), map::player_in_field(), player_on_couch(), pldrive(), item_location::impl::item_on_person::position(), firestarter_actor::prep_firestarter_use(), npc::pretend_fire(), print_aim(), npc::print_info(), print_items(), game::process_artifact(), process_bionic(), process_effects_internal(), process_items(), relic_funcs::process_recharge_entry(), sounds::process_sound_markers(), process_turn(), prompt_disassemble_single(), activity_handlers::pry_nails_finish(), iexamine::quern_examine(), plot_options::query_seed(), avatar_action::ramp_move(), mattack::ranged_pull(), reach_attack(), npc::reach_omt_destination(), read(), recalc_speed_bonus(), ranged::recoil_vehicle(), activity_handlers::reload_finish(), vehicle::remote_controlled(), monexamine::remove_bag_from(), render_wind(), veh_utils::repair_part(), requirements_map(), firestarter_actor::resolve_firestarter_use(), iuse::robotcontrol(), iuse::robotcontrol_can_target(), rod_fish(), character_funcs::roll_can_sleep(), rooted(), rooted_message(), route_adjacent(), target_ui::run(), examine_item_menu::run(), run_cost(), avatar::save_map_memory(), npc::say(), character_funcs::search_surroundings(), npc::see_item_say_smth(), sees(), sees_with_infrared(), conditional_t< T >::set_is_driving(), set_item_inventory(), avatar::set_movement_mode(), conditional_t< T >::set_npc_role_nearby(), talk_effect_fun_t::set_u_buy_monster(), monster::setpos(), npc::setpos(), activity_handlers::shear_finish(), npc::shift(), shout(), show_armor_layers_ui(), iexamine::shrub_marloss(), sight_range(), sinkhole_safety_roll(), smash(), smoker_activate(), iexamine::smoker_options(), spawn_animal(), spawn_spores(), activity_handlers::spellcasting_finish(), spores(), standard_npc::standard_npc(), autodrive_activity_actor::start(), activity_handlers::start_fire_do_turn(), game::start_game(), npc::stow_item(), suffer_from_bad_bionics(), suffer_from_other_mutations(), suffer_from_radiation(), suffer_from_schizophrenia(), suffer_in_sunlight(), suffer_while_underwater(), game::swap_critters(), avatar_action::swim(), symbol_color(), takeoff(), iuse::talking_doll(), iuse::tazer(), ranged::throw_item(), toolweapon_off(), toolweapon_on(), iuse::tow_attach(), iexamine::trap(), activity_handlers::travel_do_turn(), npc::travel_overmap(), iexamine::tree_hickory(), iexamine::tree_maple_tapped(), iexamine::tree_marloss(), explosion_iuse::trigger_explosion(), try_consume(), avatar_funcs::try_disarm_npc(), try_fuel_fire(), game::try_get_left_click_action(), game::try_get_right_click_action(), try_reject_mutagen(), salvage_actor::try_to_cut_up(), avatar_funcs::try_to_sleep(), iuse::unfold_generic(), uninstall_bionic(), avatar_funcs::unload_item(), update_bodytemp(), update_needs(), npc::update_path(), game::update_stair_monsters(), editmap::update_view_with_help(), iuse_transform::use(), countdown_actor::use(), explosion_iuse::use(), unfold_vehicle_iuse::use(), delayed_transform_iuse::use(), set_transform_iuse::use(), set_transformed_iuse::use(), place_monster_iuse::use(), place_npc_iuse::use(), pick_lock_actor::use(), deploy_furn_actor::use(), firestarter_actor::use(), fireweapon_off_actor::use(), fireweapon_on_actor::use(), manualnoise_actor::use(), musical_instrument_actor::use(), holster_actor::use(), heal_actor::use(), place_trap_actor::use(), emit_actor::use(), mutagen_iv_actor::use(), deploy_tent_actor::use(), unpack_actor::use(), use_charges(), use_fire(), valid_aoe_technique(), game::validate_camps(), game::vertical_move(), activity_handlers::vibe_do_turn(), vomit(), iuse::vortex(), wait(), game::walk_move(), npc::warn_about(), iuse::weather_tool(), npc::wield(), avatar_action::wield(), npc::wield_better_weapon(), npc::wont_hit_friend(), npc::worker_downtime(), and game::zones_manager().

◆ position_to_wear_new_item()

std::list< item >::iterator Character::position_to_wear_new_item ( const item new_item)
protected

Return the position in the worn list where new_item would be put by default.

Definition at line 3953 of file character.cpp.

3954{
3955 // By default we put this item on after the last item on the same or any
3956 // lower layer.
3957 return std::find_if(
3958 worn.rbegin(), worn.rend(),
3959 [&]( const item & w ) {
3960 return w.get_layer() <= new_item.get_layer();
3961 }
3962 ).base();
3963}

References worn.

Referenced by item_encumb(), and wear_item().

◆ posx()

◆ posy()

◆ posz()

int Character::posz ( ) const
inlineoverridevirtual

◆ pour_into() [1/2]

bool Character::pour_into ( item container,
item liquid 
)

Try to pour the given liquid into the given container/vehicle.

The transferred charges are removed from the liquid item. Check the charges of afterwards to see if anything has been transferred at all. The functions do not consume any move points.

Returns
Whether anything has been moved at all. false indicates the transfer is not possible at all. true indicates at least some of the liquid has been moved.

Definition at line 6376 of file character.cpp.

6377{
6378 std::string err;
6379 const int amount = container.get_remaining_capacity_for_liquid( liquid, *this, &err );
6380
6381 if( !err.empty() ) {
6382 add_msg_if_player( m_bad, err );
6383 return false;
6384 }
6385
6386 add_msg_if_player( _( "You pour %1$s into the %2$s." ), liquid.tname(), container.tname() );
6387
6388 container.fill_with( liquid, amount );
6389 inv.unsort();
6390
6391 if( liquid.charges > 0 ) {
6392 add_msg_if_player( _( "There's some left over!" ) );
6393 }
6394
6395 return true;
6396}
void fill_with(item &liquid, int amount=INFINITE_CHARGES)
Fill item with liquid up to its capacity.
Definition: item.cpp:8584
int get_remaining_capacity_for_liquid(const item &liquid, bool allow_bucket=false, std::string *err=nullptr) const
How much more of this liquid (in charges) can be put in this container.
Definition: item.cpp:8446

References _, Creature::add_msg_if_player(), item::charges, item::fill_with(), item::get_remaining_capacity_for_liquid(), inv, m_bad, item::tname(), and inventory::unsort().

Referenced by activity_handlers::fill_liquid_do_turn().

◆ pour_into() [2/2]

bool Character::pour_into ( vehicle veh,
item liquid 
)

Definition at line 6398 of file character.cpp.

6399{
6400 auto sel = [&]( const vehicle_part & pt ) {
6401 return pt.is_tank() && pt.can_reload( liquid );
6402 };
6403
6404 auto stack = units::legacy_volume_factor / liquid.type->stack_size;
6405 auto title = string_format( _( "Select target tank for <color_%s>%.1fL %s</color>" ),
6406 get_all_colors().get_name( liquid.color() ),
6407 round_up( to_liter( liquid.charges * stack ), 1 ),
6408 liquid.tname() );
6409
6410 auto &tank = veh_interact::select_part( veh, sel, title );
6411 if( !tank ) {
6412 return false;
6413 }
6414
6415 tank.fill_with( liquid );
6416
6417 //~ $1 - vehicle name, $2 - part name, $3 - liquid type
6418 add_msg_if_player( _( "You refill the %1$s's %2$s with %3$s." ),
6419 veh.name, tank.name(), liquid.type_name() );
6420
6421 if( liquid.charges > 0 ) {
6422 add_msg_if_player( _( "There's some left over!" ) );
6423 }
6424 return true;
6425}
double round_up(double val, unsigned int dp)
Round a value up at a given decimal place.
nc_color color() const
Returns the default color of the item (e.g.
Definition: item.cpp:4935
static vehicle_part & select_part(const vehicle &veh, const part_selector &sel, const std::string &title=std::string())
Prompt for a part matching the selector function.
std::string name
Definition: vehicle.h:1874
color_manager & get_all_colors()
Definition: color.cpp:45
std::string title(holiday current_holiday)
Definition: path_info.cpp:326
constexpr double to_liter(const volume &v)
Definition: units_volume.h:43
static constexpr volume legacy_volume_factor
Definition: units_volume.h:50
Structure, describing vehicle part (i.e., wheel, seat)
Definition: vehicle.h:186

References _, Creature::add_msg_if_player(), item::charges, item::color(), get_all_colors(), get_name(), units::legacy_volume_factor, vehicle::name, round_up(), veh_interact::select_part(), itype::stack_size, string_format(), PATH_INFO::title(), item::tname(), units::to_liter(), item::type, and item::type_name().

◆ power_rating()

float Character::power_rating ( ) const
overridevirtual

Returns an approximation of the creature's strength.

Implements Creature.

Definition at line 9975 of file character.cpp.

9976{
9977 const item &weapon = primary_weapon();
9978 int dmg = std::max( { weapon.damage_melee( DT_BASH ),
9979 weapon.damage_melee( DT_CUT ),
9980 weapon.damage_melee( DT_STAB )
9981 } );
9982
9983 int ret = 2;
9984 // Small guns can be easily hidden from view
9985 if( weapon.volume() <= 250_ml ) {
9986 ret = 2;
9987 } else if( weapon.is_gun() ) {
9988 ret = 4;
9989 } else if( dmg > 12 ) {
9990 ret = 3; // Melee weapon or weapon-y tool
9991 }
9992 if( get_size() == MS_HUGE ) {
9993 ret += 1;
9994 }
9995 if( is_wearing_power_armor( nullptr ) ) {
9996 ret = 5; // No mercy!
9997 }
9998 return ret;
9999}

References item::damage_melee(), DT_BASH, DT_CUT, DT_STAB, get_size(), item::is_gun(), is_wearing_power_armor(), MS_HUGE, primary_weapon(), cata::hash64_detail::ret, and item::volume().

◆ practice()

void Character::practice ( const skill_id id,
int  amount,
int  cap = 99,
bool  suppress_warning = false 
)

This handles giving xp for a skill.

Definition at line 3415 of file character.cpp.

3416{
3417 SkillLevel &level = get_skill_level_object( id );
3418 const Skill &skill = id.obj();
3419 std::string skill_name = skill.name();
3420
3421 if( !level.can_train() && !in_sleep_state() ) {
3422 // If leveling is disabled, don't train, don't drain focus, don't print anything
3423 // Leaving as a skill method rather than global for possible future skill cap setting
3424 return;
3425 }
3426
3427 const auto highest_skill = [&]() {
3428 std::pair<skill_id, int> result( skill_id::NULL_ID(), -1 );
3429 for( const auto &pair : *_skills ) {
3430 const SkillLevel &lobj = pair.second;
3431 if( lobj.level() > result.second ) {
3432 result = std::make_pair( pair.first, lobj.level() );
3433 }
3434 }
3435 return result.first;
3436 };
3437
3438 const bool isSavant = has_trait( trait_SAVANT );
3439 const skill_id savantSkill = isSavant ? highest_skill() : skill_id::NULL_ID();
3440
3441 amount = adjust_for_focus( amount );
3442
3443 if( has_trait( trait_PACIFIST ) && skill.is_combat_skill() ) {
3444 if( !one_in( 3 ) ) {
3445 amount = 0;
3446 }
3447 }
3448 if( has_trait_flag( "PRED2" ) && skill.is_combat_skill() ) {
3449 if( one_in( 3 ) ) {
3450 amount *= 2;
3451 }
3452 }
3453 if( has_trait_flag( "PRED3" ) && skill.is_combat_skill() ) {
3454 amount *= 2;
3455 }
3456
3457 if( has_trait_flag( "PRED4" ) && skill.is_combat_skill() ) {
3458 amount *= 3;
3459 }
3460
3461 if( isSavant && id != savantSkill ) {
3462 amount /= 2;
3463 }
3464
3465 if( amount > 0 && get_skill_level( id ) > cap ) { //blunt grinding cap implementation for crafting
3466 amount = 0;
3467 if( !suppress_warning && one_in( 5 ) ) {
3469 }
3470 }
3471 if( amount > 0 && level.isTraining() ) {
3472 int oldLevel = get_skill_level( id );
3473 get_skill_level_object( id ).train( amount );
3474 int newLevel = get_skill_level( id );
3475 if( newLevel > oldLevel ) {
3476 g->events().send<event_type::gains_skill_level>( getID(), id, newLevel );
3477 }
3478 if( is_player() && newLevel > oldLevel ) {
3479 add_msg( m_good, _( "Your skill in %s has increased to %d!" ), skill_name, newLevel );
3480 }
3481 if( is_player() && newLevel > cap ) {
3482 //inform player immediately that the current recipe can't be used to train further
3483 add_msg( m_info, _( "You feel that %s tasks of this level are becoming trivial." ),
3484 skill_name );
3485 }
3486
3487 int chance_to_drop = focus_pool;
3488 focus_pool -= chance_to_drop / 100;
3489 // Apex Predators don't think about much other than killing.
3490 // They don't lose Focus when practicing combat skills.
3491 if( ( rng( 1, 100 ) <= ( chance_to_drop % 100 ) ) && ( !( has_trait_flag( "PRED4" ) &&
3492 skill.is_combat_skill() ) ) ) {
3493 focus_pool--;
3494 }
3495 }
3496
3498}
static const trait_id trait_SAVANT("SAVANT")
static const trait_id trait_PACIFIST("PACIFIST")
SkillLevel & get_skill_level_object(const skill_id &ident)
Definition: character.cpp:3344
int adjust_for_focus(int amount) const
Definition: character.cpp:9938
bool can_train() const
Definition: skill.cpp:311
bool isTraining() const
Definition: skill.h:117
void practice()
Definition: skill.cpp:297
void train(int amount, bool skip_scaling=false)
Definition: skill.cpp:223
void show_skill_capped_notice(const Character &who, const skill_id &id)
This shows warning to the player that their current activity will not give them xp.

References _, _skills, add_msg(), adjust_for_focus(), SkillLevel::can_train(), focus_pool, g, gains_skill_level, get_skill_level(), get_skill_level_object(), getID(), has_trait(), has_trait_flag(), id, in_sleep_state(), Skill::is_combat_skill(), Creature::is_player(), SkillLevel::isTraining(), SkillLevel::level(), m_good, m_info, Skill::name(), string_id< Skill >::NULL_ID(), one_in(), SkillLevel::practice(), rng(), character_funcs::show_skill_capped_notice(), SkillLevel::train(), trait_PACIFIST, and trait_SAVANT.

Referenced by vehicle::act_on_map(), activity_handlers::butcher_finish(), butchery_drops_harvest(), talk_function::companion_skill_trainer(), crafting::complete_disassemble(), veh_interact::complete_vehicle(), player::craft_skill_gain(), salvage_actor::cut_up(), character_funcs::do_pause(), iuse::einktabletpc(), heal_actor::finish_using(), ranged::fire_gun(), activity_handlers::fish_do_turn(), iuse::fish_trap(), iexamine::fvat_full(), iuse::gun_repair(), hack_attempt(), computer_session::hack_attempt(), hackveh(), install_bionics(), place_trap_actor::data::load(), activity_handlers::make_zlave_finish(), melee_train(), iuse::multicooker(), on_dodge(), perform_special_attacks(), pick_plant(), vehicle::pldrive(), iexamine::practice_survival_while_foraging(), activity_handlers::pry_nails_finish(), activity_handlers::pulp_do_turn(), repair_item_actor::repair(), veh_utils::repair_part(), activity_handlers::robot_control_finish(), talk_trial::roll(), smash(), activity_handlers::start_fire_finish(), activity_handlers::study_spell_finish(), avatar_action::swim(), ranged::throw_item(), place_trap_actor::use(), and sew_advanced_actor::use().

◆ primary_weapon() [1/2]

item & Character::primary_weapon ( )

Legacy code hack, don't use.

Returns the first wielded weapon or a null item. Use wielded_items instead.

Definition at line 166 of file melee.cpp.

167{
168 return const_cast<item &>( const_cast<const Character *>( this )->primary_weapon() );
169}

References primary_weapon().

Referenced by activate_bionic(), npc::aim(), allocated_invlets(), npc::alt_attack(), apply_damage(), avatar_action::autoattack(), npc::average_damage_dealt(), best_shield(), mattack::bio_op_disarm(), mattack::bio_op_takedown(), block_hit(), npc::can_reload_current(), can_wear(), can_wield(), cast_spell(), npc::character_danger(), check_art_charge_req(), npc::check_or_use_weapon_cbm(), consume(), mattack::copbot(), crafting_inventory(), deactivate_bionic(), deal_damage(), npc::decide_needs(), dismount(), throw_activity_actor::do_turn(), iuse::ehandcuffs(), explosion_handler::emp_blast(), npc::execute_action(), extended_description(), npc::faction_display(), fire(), ranged::fire_gun(), avatar_action::fire_wielded_weapon(), character_funcs::fmt_wielded_weapon(), forced_dismount(), npc::form_opinion(), mattack::frag(), get_item_position(), get_overlay_ids(), aim_activity_actor::get_weapon(), get_weight(), give_item_to(), mattack::grab(), game::handle_action(), handle_problematic_pickup(), hardcoded_effects(), hardcoded_mutation_attack(), i_at(), i_rem(), npc_trading::init_buying(), character_effects::intimidation(), inv_dump(), npc::invalidate_range_cache(), is_armed(), steal_inventory_preset::is_shown(), ma_requirements::is_valid_character(), is_wielding(), item_handling_cost(), mdeath::jabberwock(), ma_style_callback::key(), game::list_monsters(), load(), character_martial_arts::martialart_use_message(), melee_attack(), melee_special_effects(), avatar_action::mend(), npc::method_of_attack(), npc::move(), avatar_action::move(), npc::move_pause(), npc::move_to(), npc::npc_dismount(), on_dodge(), parse_tags(), monexamine::pet_menu(), pick_one_up(), avatar_action::plthrow(), power_rating(), primary_weapon(), print_aim(), npc::print_info(), game::process_artifact(), item::process_extinguish(), process_items(), mattack::pull_metal_weapon(), activity_handlers::pulp_do_turn(), reach_attack(), reach_attack(), remove_weapon(), mattack::rifle(), mattack::riotbot(), examine_item_menu::run(), character_martial_arts::selected_style_name(), conditional_t< T >::set_can_stow_weapon(), gun_actor::shoot(), short_description_parts(), smash(), npc::smash_ability(), starting_inv(), npc::starting_weapon(), store(), npc::stow_item(), suffer_from_bad_bionics(), suffer_from_schizophrenia(), suffer_from_sunburn(), mattack::tankgun(), avatar_funcs::try_disarm_npc(), game::try_get_right_click_action(), character_funcs::try_wield_contents(), unwield(), update_bodytemp(), trading_window::update_win(), use_amount(), used_weapon(), npc::value(), wear_possessed(), weight_carried_reduced_by(), weather_effect::wet_player(), npc::wield(), avatar::wield(), npc::wield_better_weapon(), npc_ai::wielded_value(), and memorial_logger::write().

◆ primary_weapon() [2/2]

const item & Character::primary_weapon ( ) const

Definition at line 149 of file melee.cpp.

150{
151 if( get_body().find( body_part_arm_r ) == get_body().end() ) {
152 debugmsg( "primary_weapon called before set_anatomy" );
153 return null_item_reference();
154 }
155
156 // TODO: Remove unconst hacks
157 const std::shared_ptr<item> &wielded_const = get_part( body_part_arm_r ).wielding.wielded;
158 std::shared_ptr<item> &wielded = const_cast<std::shared_ptr<item> &>( wielded_const );
159 if( wielded == nullptr ) {
160 wielded = std::make_shared<item>();
161 }
162
163 return *wielded;
164}
const bodypart_str_id body_part_arm_r("arm_r")
wield_status wielding
Definition: bodypart.h:178
std::shared_ptr< item > wielded
Definition: bodypart.h:160

References body_part_arm_r, debugmsg, detail::find(), Creature::get_body(), Creature::get_part(), null_item_reference(), wield_status::wielded, and bodypart::wielding.

◆ print_health()

void Character::print_health ( ) const

Definition at line 4219 of file character.cpp.

4220{
4221 if( !is_player() ) {
4222 return;
4223 }
4224 int current_health = get_healthy();
4225 if( has_trait( trait_SELFAWARE ) ) {
4226 add_msg_if_player( _( "Your current health value is %d." ), current_health );
4227 }
4228
4229 static const std::map<int, std::string> msg_categories = {
4230 { -100, "health_horrible" },
4231 { -50, "health_very_bad" },
4232 { -10, "health_bad" },
4233 { 10, "" },
4234 { 50, "health_good" },
4235 { 100, "health_very_good" },
4236 { INT_MAX, "health_great" }
4237 };
4238
4239 auto iter = msg_categories.lower_bound( current_health );
4240 if( iter != msg_categories.end() && !iter->second.empty() ) {
4241 const translation msg = SNIPPET.random_from_category( iter->second ).value_or( translation() );
4242 add_msg_if_player( current_health > 0 ? m_good : m_bad, "%s", msg );
4243 }
4244}

References _, Creature::add_msg_if_player(), get_healthy(), has_trait(), Creature::is_player(), m_bad, m_good, snippet_library::random_from_category(), SNIPPET, and trait_SELFAWARE.

Referenced by activate_mutation(), and avatar::wake_up().

◆ print_info()

int Character::print_info ( const catacurses::window w,
int  vStart,
int  vLines,
int  column 
) const
overridevirtual

Write information about this creature.

Parameters
wthe window to print the text into.
vStartvertical start to print, that means the first line to print.
vLinesnumber of lines to print at most (printing less is fine).
columnhorizontal start to print (column), horizontal end is one character before the right border of the window (to keep the border).
Returns
The line just behind the last printed line, that means multiple calls to this can be stacked, the return value is acceptable as vStart for the next call without creating empty lines or overwriting lines.

Implements Creature.

Reimplemented in npc.

Definition at line 10354 of file character.cpp.

10355{
10356 mvwprintw( w, point( column, vStart++ ), _( "You (%s)" ), name );
10357 return vStart;
10358}
void mvwprintw(const window &win, point p, const std::string &text)

References _, catacurses::mvwprintw(), and name.

◆ process_bionic()

void Character::process_bionic ( bionic bio)

Handles bionic effects over time of the entered bionic.

Definition at line 1568 of file bionics.cpp.

1569{
1570 if( ( !bio.id->fuel_opts.empty() || bio.id->is_remote_fueled ) && bio.is_auto_start_on() ) {
1571 const float start_threshold = bio.get_auto_start_thresh();
1572 std::vector<itype_id> fuel_available = get_fuel_available( bio.id );
1573 if( bio.id->is_remote_fueled ) {
1574 const itype_id rem_fuel = find_remote_fuel();
1575 const std::string rem_amount = get_value( "rem_" + rem_fuel.str() );
1576 int rem_fuel_stock = 0;
1577 if( !rem_amount.empty() ) {
1578 rem_fuel_stock = std::stoi( rem_amount );
1579 }
1580 if( !rem_fuel.is_empty() && ( rem_fuel_stock > 0 ||
1581 item( rem_fuel ).has_flag( flag_PERPETUAL ) ) ) {
1582 fuel_available.emplace_back( rem_fuel );
1583 }
1584 }
1585 if( !fuel_available.empty() && get_power_level() <= start_threshold * get_max_power_level() ) {
1586 g->u.activate_bionic( bio );
1587 } else if( get_power_level() <= start_threshold * get_max_power_level() &&
1588 calendar::once_every( 1_hours ) ) {
1589 add_msg_player_or_npc( m_bad, _( "Your %s does not have enough fuel to use Auto Start." ),
1590 _( "<npcname>'s %s does not have enough fuel to use Auto Start." ),
1591 bio.info().name );
1592 }
1593 }
1594
1595 // Only powered bionics should be processed
1596 if( !bio.powered ) {
1597 passive_power_gen( bio );
1598 return;
1599 }
1600
1601 // These might be affected by environmental conditions, status effects, faulty bionics, etc.
1602 int discharge_factor = 1;
1603 int discharge_rate = 1;
1604
1605 if( bio.charge_timer > 0 ) {
1606 bio.charge_timer -= discharge_rate;
1607 } else {
1608 if( bio.info().charge_time > 0 ) {
1609 if( bio.info().has_flag( STATIC( flag_str_id( "BIONIC_POWER_SOURCE" ) ) ) ) {
1610 // Convert fuel to bionic power
1611 burn_fuel( bio );
1612 // This is our first turn of charging, so subtract a turn from the recharge delay.
1613 bio.charge_timer = std::max( 0, bio.info().charge_time - 1 );
1614 } else {
1615 // Try to recharge our bionic if it is made for it
1616 units::energy cost = 0_J;
1617 bool recharged = attempt_recharge( *this, bio, cost, discharge_factor, discharge_rate );
1618 if( !recharged ) {
1619 // No power to recharge, so deactivate
1620 bio.powered = false;
1621 add_msg_if_player( m_neutral, _( "Your %s powers down." ), bio.info().name );
1622 // This purposely bypasses the deactivation cost
1623 deactivate_bionic( bio, true );
1624 return;
1625 }
1626 if( cost > 0_J ) {
1627 mod_power_level( -cost );
1628 }
1629 }
1630 }
1631 }
1632
1633 // Bionic effects on every turn they are active go here.
1634 if( bio.id == bio_remote ) {
1635 if( g->remoteveh() == nullptr && get_value( "remote_controlling" ).empty() ) {
1636 bio.powered = false;
1637 add_msg_if_player( m_warning, _( "Your %s has lost connection and is turning off." ),
1638 bio.info().name );
1639 }
1640 } else if( bio.id == bio_hydraulics ) {
1641 // Sound of hissing hydraulic muscle! (not quite as loud as a car horn)
1642 sounds::sound( pos(), 19, sounds::sound_t::activity, _( "HISISSS!" ), false, "bionic",
1643 static_cast<std::string>( bio_hydraulics ) );
1644 } else if( bio.id == bio_nanobots ) {
1645 int threshold_kcal = bio.info().kcal_trigger > 0 ? 0.85f * max_stored_kcal() +
1646 bio.info().kcal_trigger : 0;
1647 const auto can_use_bionic = [this, &bio, threshold_kcal]() -> bool {
1648 const bool is_kcal_sufficient = get_stored_kcal() >= threshold_kcal;
1649 const bool is_power_sufficient = get_power_level() >= bio.info().power_trigger;
1650 return is_kcal_sufficient && is_power_sufficient;
1651 };
1652 if( get_stored_kcal() < threshold_kcal ) {
1653 bio.powered = false;
1654 add_msg_if_player( m_warning, _( "Your %s shut down to conserve calories." ), bio.info().name );
1655 deactivate_bionic( bio );
1656 return;
1657 }
1658 if( calendar::once_every( 30_turns ) ) {
1659 std::vector<effect *> bleeding_list = get_all_effects_of_type( effect_bleed );
1660 // Essential parts (Head/Torso) first.
1661 std::sort( bleeding_list.begin(), bleeding_list.end(),
1662 []( effect * a, effect * b ) {
1663 return a->get_bp()->essential > b->get_bp()->essential;
1664 } );
1665 if( !bleeding_list.empty() ) {
1666 effect *e = bleeding_list[0];
1667 if( e->get_intensity() > 1 ) {
1668 add_msg_if_player( "Your %s slow the bleeding on your %s", bio.info().name, e->get_bp()->name );
1669 e->mod_intensity( -1, false );
1670 } else {
1671 add_msg_if_player( "Your %s staunch the bleeding on your %s", bio.info().name, e->get_bp()->name );
1672 e->set_removed();
1673 }
1674 }
1675 if( calendar::once_every( 2_minutes ) ) {
1676 std::vector<bodypart_id> damaged_hp_parts;
1677 std::vector<effect *> mending_list;
1678
1679 for( const bodypart_id &bp : get_all_body_parts( true ) ) {
1680 const int hp_cur = get_part_hp_cur( bp );
1681 if( !is_limb_broken( bp ) && hp_cur < get_part_hp_max( bp ) ) {
1682 damaged_hp_parts.push_back( bp );
1683 } else if( has_effect( effect_mending, bp.id() ) &&
1685 effect *e = &get_effect( effect_mending, bp->token );
1686 mending_list.push_back( e );
1687 }
1688 }
1689 if( !damaged_hp_parts.empty() ) {
1690 // Essential parts are considered 10 HP lower than non-essential parts for the purpose of determining priority.
1691 // I'd use the essential_value, but it's tied up in the heal_actor class of iuse_actor.
1692 std::sort( damaged_hp_parts.begin(), damaged_hp_parts.end(),
1693 [this]( const bodypart_id & a, const bodypart_id & b ) {
1694 return ( get_part_hp_cur( a ) - a->essential * 10 ) < ( get_part_hp_cur( b ) - b->essential * 10 );
1695 } );
1696 for( bodypart_id &bpid : damaged_hp_parts ) {
1697 if( !can_use_bionic() ) {
1698 return;
1699 }
1700 heal( bpid, 1 );
1703 }
1704 }
1705 if( !mending_list.empty() ) {
1706 for( effect *e : mending_list ) {
1707 if( !can_use_bionic() ) {
1708 return;
1709 }
1710 e->mod_duration( e->get_max_duration() / 100 );
1713 }
1714 }
1715 }
1716 }
1717 } else if( bio.id == bio_painkiller ) {
1718 const int pkill = get_painkiller();
1719 const int pain = get_pain();
1720 const units::energy trigger_cost = bio.info().power_trigger;
1721 int max_pkill = std::min( 150, pain );
1722 if( pkill < max_pkill ) {
1723 mod_painkiller( 1 );
1724 mod_power_level( -trigger_cost );
1725 }
1726
1727 // Only dull pain so extreme that we can't pkill it safely
1728 if( pkill >= 150 && pain > pkill && get_stim() > -150 ) {
1729 mod_pain( -1 );
1730 // Negative side effect: negative stim
1731 mod_stim( -1 );
1732 mod_power_level( -trigger_cost );
1733 }
1734 } else if( bio.id == bio_gills ) {
1735 if( has_effect( effect_asthma ) ) {
1737 _( "You feel your throat open up and air filling your lungs!" ) );
1739 }
1740 } else if( bio.id == bio_evap ) {
1741 // Aero-Evaporator provides water at 60 watts with 2 L / kWh efficiency
1742 // which is 10 mL per 5 minutes. Humidity can modify the amount gained.
1743 if( calendar::once_every( 5_minutes ) ) {
1744 const w_point &weatherPoint = get_weather().get_precise();
1745 int humidity = get_local_humidity( weatherPoint.humidity, get_weather().weather_id,
1746 g->is_sheltered( g->u.pos() ) );
1747 // in thirst units = 5 mL water
1748 int water_available = std::lround( humidity * 3.0 / 100.0 );
1749 // At 50% relative humidity or more, the player will draw 10 mL
1750 // At 16% relative humidity or less, the bionic will give up
1751 if( water_available == 0 ) {
1753 _( "There is not enough humidity in the air for your %s to function." ),
1754 bio.info().name );
1755 deactivate_bionic( bio );
1756 } else if( water_available == 1 ) {
1758 _( "Your %s issues a low humidity warning. Efficiency is reduced." ),
1759 bio.info().name );
1760 }
1761
1762 mod_thirst( -water_available );
1763 }
1764
1767 _( "You are properly hydrated. Your %s chirps happily." ),
1768 bio.info().name );
1769 deactivate_bionic( bio );
1770 }
1771 } else if( bio.id == bio_ads ) {
1772 if( bio.charge_timer < 2 ) {
1773 bio.charge_timer = 2;
1774 }
1775 if( bio.energy_stored < 150_kJ ) {
1776 // Max recharge rate is influenced by whether you've been hit or not.
1777 // See character.cpp for how charge_timer keeps track of that for this bionic.
1778 units::energy max_rate = 10_kJ;
1779 if( bio.charge_timer > 2 ) {
1780 max_rate /= 2;
1781 }
1782 units::energy ads_recharge = std::min( max_rate, 150_kJ - bio.energy_stored );
1783 if( ads_recharge < get_power_level() ) {
1784 mod_power_level( - ads_recharge );
1785 bio.energy_stored += ads_recharge;
1786 } else if( get_power_level() != 0_kJ ) {
1789 }
1790 if( bio.energy_stored == 150_kJ ) {
1791 add_msg_if_player( m_good, _( "Your %s quietens to a satisfied thrum." ), bio.info().name );
1792 }
1793 } else if( bio.energy_stored > 150_kJ ) {
1794 bio.energy_stored = 150_kJ;
1795 }
1796 } else if( bio.id == afs_bio_dopamine_stimulators ) {
1797 add_morale( MORALE_FEELING_GOOD, 20, 20, 30_minutes, 20_minutes, true );
1798 } else if( bio.id == bio_radscrubber ) {
1799 if( calendar::once_every( 10_minutes ) ) {
1800 const units::energy trigger_cost = bio.info().power_trigger;
1801
1802 if( get_rad() > 0 && bio.energy_stored >= trigger_cost ) {
1803 add_msg_if_player( m_good, _( "Your %s completed a scrubbing cycle." ), bio.info().name );
1804
1805 mod_rad( std::max( -10, -get_rad() ) );
1806 mod_power_level( -trigger_cost );
1807 }
1808 }
1809 }
1810}
static const efftype_id effect_bleed("bleed")
static bool attempt_recharge(Character &p, bionic &bio, units::energy &amount, int factor=1, int rate=1)
Definition: bionics.cpp:1548
static const efftype_id effect_asthma("asthma")
static const bionic_id afs_bio_dopamine_stimulators("afs_bio_dopamine_stimulators")
static const bionic_id bio_nanobots("bio_nanobots")
static const trait_id trait_REGEN_LIZ("REGEN_LIZ")
static const bionic_id bio_radscrubber("bio_radscrubber")
static const bionic_id bio_gills("bio_gills")
static const std::string flag_SPLINT("SPLINT")
static const efftype_id effect_mending("mending")
void mod_painkiller(int npkill)
Modifies intensity of painkillers
Definition: character.cpp:9788
void passive_power_gen(bionic &bio)
Passively produce power from PERPETUAL fuel.
Definition: bionics.cpp:1356
std::vector< const effect * > get_all_effects_of_type(const efftype_id &eff_id) const
Returns pointers to all effects matching given type.
Definition: creature.cpp:1270
void set_removed()
Definition: effect.h:249
constexpr double a
Definition: magic.cpp:1030
const morale_type MORALE_FEELING_GOOD("morale_feeling_good")
int kcal_trigger
Kcal cost when the bionic's special effect is triggered.
Definition: bionics.h:45
float get_auto_start_thresh() const
Definition: bionics.cpp:2824
bool is_auto_start_on() const
Definition: bionics.cpp:2829
translation name
Definition: bodypart.h:96

References _, a, sounds::activity, add_morale(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), afs_bio_dopamine_stimulators, attempt_recharge(), b, bio_ads, bio_evap, bio_gills, bio_hydraulics, bio_nanobots, bio_painkiller, bio_radscrubber, bio_remote, burn_fuel(), bionic_data::charge_time, bionic::charge_timer, deactivate_bionic(), effect_asthma, effect_bleed, effect_mending, bionic::energy_stored, find_remote_fuel(), flag_PERPETUAL(), flag_SPLINT(), bionic_data::fuel_opts, g, Creature::get_all_body_parts(), Creature::get_all_effects_of_type(), bionic::get_auto_start_thresh(), effect::get_bp(), Creature::get_effect(), get_fuel_available(), effect::get_intensity(), get_local_humidity(), get_max_power_level(), Creature::get_pain(), get_painkiller(), Creature::get_part_hp_cur(), Creature::get_part_hp_max(), get_power_level(), weather_manager::get_precise(), get_rad(), get_stim(), get_stored_kcal(), get_thirst(), Creature::get_value(), get_weather(), Creature::has_effect(), bionic_data::has_flag(), Creature::has_flag(), has_trait(), heal(), w_point::humidity, hydrated, bionic::id, string_id< T >::id(), bionic::info(), bionic::is_auto_start_on(), string_id< T >::is_empty(), is_limb_broken(), bionic_data::is_remote_fueled, bionic_data::kcal_trigger, m_bad, m_good, m_mixed, m_neutral, m_warning, max_stored_kcal(), effect::mod_intensity(), mod_pain(), mod_painkiller(), mod_power_level(), mod_rad(), mod_stim(), mod_stored_kcal(), mod_thirst(), MORALE_FEELING_GOOD, bionic_data::name, body_part_type::name, calendar::once_every(), Creature::pain, passive_power_gen(), pkill, pos(), bionic_data::power_trigger, bionic::powered, Creature::remove_effect(), effect::set_removed(), sounds::sound(), STATIC, string_id< T >::str(), trait_REGEN_LIZ, and worn_with_flag().

Referenced by suffer().

◆ process_effects_internal()

void Character::process_effects_internal ( )
overridevirtual

Processes human-specific effects of effects before calling Creature::process_effects().

Implements Creature.

Definition at line 537 of file character_turn.cpp.

538{
539 //Special Removals
540 if( has_effect( effect_darkness ) && g->is_in_sunlight( pos() ) ) {
542 }
544 vomit();
546 add_msg_if_player( m_bad, _( "We have mistakenly colonized a local guide! Purging now." ) );
547 }
558 add_msg_if_player( m_good, _( "Something writhes and inside of you as it dies." ) );
559 }
566 }
569 add_msg_if_player( m_good, _( "Your bowels gurgle as something inside them dies." ) );
570 }
571
572 //Human only effects
573 for( auto &elem : *effects ) {
574 for( auto &_effect_it : elem.second ) {
575 if( !_effect_it.second.is_removed() ) {
576 process_one_effect( _effect_it.second, false );
577 }
578 }
579 }
580}
static const efftype_id effect_bloodworms("bloodworms")
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_dermatik("dermatik")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const efftype_id effect_tapeworm("tapeworm")
static const trait_id trait_PARAIMMUNE("PARAIMMUNE")
static const efftype_id effect_darkness("darkness")
static const efftype_id effect_paincysts("paincysts")
static const trait_id trait_EATHEALTH("EATHEALTH")
static const trait_id trait_ACIDBLOOD("ACIDBLOOD")
static const efftype_id effect_brainworms("brainworms")
void process_one_effect(effect &it, bool is_new) override
Processes human-specific effects of an effect.

References _, Creature::add_msg_if_player(), effect_bloodworms, effect_brainworms, effect_darkness, effect_dermatik, effect_fungus, effect_paincysts, effect_tapeworm, Creature::effects, g, Creature::has_effect(), has_trait(), m_bad, m_good, pos(), process_one_effect(), Creature::remove_effect(), trait_ACIDBLOOD, trait_EATHEALTH, trait_M_IMMUNE, trait_PARAIMMUNE, and vomit().

◆ process_items()

void Character::process_items ( )

Process active items.

Definition at line 808 of file character_turn.cpp.

809{
810 item &weapon = primary_weapon();
811 if( weapon.needs_processing() && weapon.process( as_player(), pos(), false ) ) {
812 weapon = item();
813 }
814
815 std::vector<item *> inv_active = inv.active_items();
816 for( item *tmp_it : inv_active ) {
817 if( tmp_it->process( as_player(), pos(), false ) ) {
818 inv.remove_item( tmp_it );
819 }
820 }
821
822 // worn items
823 remove_worn_items_with( [this]( item & itm ) {
824 return itm.needs_processing() && itm.process( as_player(), pos(), false );
825 } );
826
827 // Active item processing done, now we're recharging.
828 std::vector<item *> active_worn_items;
829 bool weapon_active = weapon.has_flag( "USE_UPS" ) &&
830 weapon.charges < weapon.type->maximum_charges();
831 std::vector<size_t> active_held_items;
832 int ch_UPS = 0;
833 for( size_t index = 0; index < inv.size(); index++ ) {
834 item &it = inv.find_item( index );
835 itype_id identifier = it.type->get_id();
836 if( identifier == itype_UPS_off ) {
837 ch_UPS += it.ammo_remaining();
838 } else if( identifier == itype_adv_UPS_off ) {
839 ch_UPS += it.ammo_remaining() / 0.6;
840 }
841 if( it.has_flag( "USE_UPS" ) && it.charges < it.type->maximum_charges() ) {
842 active_held_items.push_back( index );
843 }
844 }
845 bool update_required = get_check_encumbrance();
846 for( item &w : worn ) {
847 if( w.has_flag( "USE_UPS" ) &&
848 w.charges < w.type->maximum_charges() ) {
849 active_worn_items.push_back( &w );
850 }
851 // Necessary for UPS in Aftershock - check worn items for charge
852 const itype_id &identifier = w.typeId();
853 if( identifier == itype_UPS_off ) {
854 ch_UPS += w.ammo_remaining();
855 } else if( identifier == itype_adv_UPS_off ) {
856 ch_UPS += w.ammo_remaining() / 0.6;
857 }
858 if( !update_required && w.encumbrance_update_ ) {
859 update_required = true;
860 }
861 w.encumbrance_update_ = false;
862 }
863 if( update_required ) {
865 }
866 if( has_active_bionic( bionic_id( "bio_ups" ) ) ) {
868 }
869 int ch_UPS_used = 0;
870
871 // Load all items that use the UPS to their minimal functional charge,
872 // The tool is not really useful if its charges are below charges_to_use
873 for( size_t index : active_held_items ) {
874 if( ch_UPS_used >= ch_UPS ) {
875 break;
876 }
877 item &it = inv.find_item( index );
878 ch_UPS_used++;
879 it.charges++;
880 }
881 if( weapon_active && ch_UPS_used < ch_UPS ) {
882 ch_UPS_used++;
883 weapon.charges++;
884 }
885 for( item *worn_item : active_worn_items ) {
886 if( ch_UPS_used >= ch_UPS ) {
887 break;
888 }
889 ch_UPS_used++;
890 worn_item->charges++;
891 }
892 if( ch_UPS_used > 0 ) {
893 use_charges( itype_UPS, ch_UPS_used );
894 }
895}
static const itype_id itype_adv_UPS_off("adv_UPS_off")
static const itype_id itype_UPS("UPS")
static const itype_id itype_UPS_off("UPS_off")
bool get_check_encumbrance() const
Definition: character.h:2020
std::vector< item * > active_items()
Definition: inventory.cpp:1089
size_t size() const
Definition: inventory.cpp:167
bool process(player *carrier, const tripoint &pos, bool activate, temperature_flag flag=temperature_flag::TEMP_NORMAL)
This is called once each turn.
Definition: item.cpp:9620
bool needs_processing() const
Whether the item should be processed (by calling process).
Definition: item.cpp:8951
int maximum_charges() const
Definition: itype.cpp:123

References inventory::active_items(), item::ammo_remaining(), Creature::as_player(), bionic_id, item::charges, inventory::find_item(), get_check_encumbrance(), itype::get_id(), get_power_level(), has_active_bionic(), item::has_flag(), inv, itype_adv_UPS_off, itype_UPS, itype_UPS_off, itype::maximum_charges(), item::needs_processing(), pos(), primary_weapon(), item::process(), inventory::remove_item(), remove_worn_items_with(), reset_encumbrance(), inventory::size(), units::to_kilojoule(), item::type, use_charges(), and worn.

Referenced by npc::on_load(), and process_turn().

◆ process_one_effect()

void Character::process_one_effect ( effect it,
bool  is_new 
)
overridevirtual

Processes human-specific effects of an effect.

Implements Creature.

Definition at line 328 of file character_turn.cpp.

329{
330 bool reduced = resists_effect( it );
331 double mod = 1;
332 body_part bp = it.get_bp()->token;
333 int val = 0;
334
335 // Still hardcoded stuff, do this first since some modify their other traits
336 hardcoded_effects( it );
337
338 const auto get_effect = [&it, is_new]( const std::string & arg, bool reduced ) {
339 if( is_new ) {
340 return it.get_amount( arg, reduced );
341 }
342 return it.get_mod( arg, reduced );
343 };
344
345 // Handle miss messages
346 auto msgs = it.get_miss_msgs();
347 if( !msgs.empty() ) {
348 for( const auto &i : msgs ) {
349 add_miss_reason( _( i.first ), static_cast<unsigned>( i.second ) );
350 }
351 }
352
353 // Handle health mod
354 val = get_effect( "H_MOD", reduced );
355 if( val != 0 ) {
356 mod = 1;
357 if( is_new || it.activated( calendar::turn, "H_MOD", val, reduced, mod ) ) {
358 int bounded = bound_mod_to_vals(
359 get_healthy_mod(), val, it.get_max_val( "H_MOD", reduced ),
360 it.get_min_val( "H_MOD", reduced ) );
361 // This already applies bounds, so we pass them through.
362 mod_healthy_mod( bounded, get_healthy_mod() + bounded );
363 }
364 }
365
366 // Handle health
367 val = get_effect( "HEALTH", reduced );
368 if( val != 0 ) {
369 mod = 1;
370 if( is_new || it.activated( calendar::turn, "HEALTH", val, reduced, mod ) ) {
372 it.get_max_val( "HEALTH", reduced ), it.get_min_val( "HEALTH", reduced ) ) );
373 }
374 }
375
376 // Handle stim
377 val = get_effect( "STIM", reduced );
378 if( val != 0 ) {
379 mod = 1;
380 if( is_new || it.activated( calendar::turn, "STIM", val, reduced, mod ) ) {
381 mod_stim( bound_mod_to_vals( get_stim(), val, it.get_max_val( "STIM", reduced ),
382 it.get_min_val( "STIM", reduced ) ) );
383 }
384 }
385
386 // Handle hunger
387 val = get_effect( "HUNGER", reduced );
388 if( val != 0 ) {
389 mod = 1;
390 if( is_new || it.activated( calendar::turn, "HUNGER", val, reduced, mod ) ) {
392 val, it.get_max_val( "HUNGER", reduced ), it.get_min_val( "HUNGER", reduced ) ) );
393 }
394 }
395
396 // Handle thirst
397 val = get_effect( "THIRST", reduced );
398 if( val != 0 ) {
399 mod = 1;
400 if( is_new || it.activated( calendar::turn, "THIRST", val, reduced, mod ) ) {
401 mod_thirst( bound_mod_to_vals( get_thirst(), val, it.get_max_val( "THIRST", reduced ),
402 it.get_min_val( "THIRST", reduced ) ) );
403 }
404 }
405
406 // Handle fatigue
407 val = get_effect( "FATIGUE", reduced );
408 // Prevent ongoing fatigue effects while asleep.
409 // These are meant to change how fast you get tired, not how long you sleep.
410 if( val != 0 && !in_sleep_state() ) {
411 mod = 1;
412 if( is_new || it.activated( calendar::turn, "FATIGUE", val, reduced, mod ) ) {
413 mod_fatigue( bound_mod_to_vals( get_fatigue(), val, it.get_max_val( "FATIGUE", reduced ),
414 it.get_min_val( "FATIGUE", reduced ) ) );
415 }
416 }
417
418 // Handle Radiation
419 val = get_effect( "RAD", reduced );
420 if( val != 0 ) {
421 mod = 1;
422 if( is_new || it.activated( calendar::turn, "RAD", val, reduced, mod ) ) {
423 mod_rad( bound_mod_to_vals( get_rad(), val, it.get_max_val( "RAD", reduced ), 0 ) );
424 // Radiation can't go negative
425 if( get_rad() < 0 ) {
426 set_rad( 0 );
427 }
428 }
429 }
430
431 // Handle Pain
432 val = get_effect( "PAIN", reduced );
433 if( val != 0 ) {
434 mod = 1;
435 if( it.get_sizing( "PAIN" ) ) {
436 if( has_trait( trait_FAT ) ) {
437 mod *= 1.5;
438 }
439 if( get_size() == MS_LARGE ) {
440 mod *= 2;
441 }
442 if( get_size() == MS_HUGE ) {
443 mod *= 3;
444 }
445 }
446 if( is_new || it.activated( calendar::turn, "PAIN", val, reduced, mod ) ) {
447 int pain_inc = bound_mod_to_vals( get_pain(), val, it.get_max_val( "PAIN", reduced ), 0 );
448 mod_pain( pain_inc );
449 if( pain_inc > 0 ) {
450 character_funcs::add_pain_msg( *this, val, bp );
451 }
452 }
453 }
454
455 // Handle Damage
456 val = get_effect( "HURT", reduced );
457 if( val != 0 ) {
458 mod = 1;
459 if( it.get_sizing( "HURT" ) ) {
460 if( has_trait( trait_FAT ) ) {
461 mod *= 1.5;
462 }
463 if( get_size() == MS_LARGE ) {
464 mod *= 2;
465 }
466 if( get_size() == MS_HUGE ) {
467 mod *= 3;
468 }
469 }
470 if( is_new || it.activated( calendar::turn, "HURT", val, reduced, mod ) ) {
471 if( bp == num_bp ) {
472 if( val > 5 ) {
473 add_msg_if_player( _( "Your %s HURTS!" ), body_part_name_accusative( bp_torso ) );
474 } else {
475 add_msg_if_player( _( "Your %s hurts!" ), body_part_name_accusative( bp_torso ) );
476 }
477 apply_damage( nullptr, bodypart_id( "torso" ), val, true );
478 } else {
479 if( val > 5 ) {
480 add_msg_if_player( _( "Your %s HURTS!" ), body_part_name_accusative( bp ) );
481 } else {
482 add_msg_if_player( _( "Your %s hurts!" ), body_part_name_accusative( bp ) );
483 }
484 apply_damage( nullptr, convert_bp( bp ).id(), val, true );
485 }
486 }
487 }
488
489 // Handle Sleep
490 val = get_effect( "SLEEP", reduced );
491 if( val != 0 ) {
492 mod = 1;
493 if( ( is_new || it.activated( calendar::turn, "SLEEP", val, reduced, mod ) ) &&
494 !has_effect( efftype_id( "sleep" ) ) ) {
495 add_msg_if_player( _( "You pass out!" ) );
497 }
498 }
499
500 // Handle painkillers
501 val = get_effect( "PKILL", reduced );
502 if( val != 0 ) {
504 if( is_new || it.activated( calendar::turn, "PKILL", val, reduced, mod ) ) {
505 mod_painkiller( bound_mod_to_vals( get_painkiller(), val, it.get_max_val( "PKILL", reduced ), 0 ) );
506 }
507 }
508
509 // Handle coughing
510 mod = 1;
511 val = 0;
512 if( it.activated( calendar::turn, "COUGH", val, reduced, mod ) ) {
513 cough( it.get_harmful_cough() );
514 }
515
516 // Handle vomiting
518 val = 0;
519 if( it.activated( calendar::turn, "VOMIT", val, reduced, mod ) ) {
520 vomit();
521 }
522
523 // Handle stamina
524 val = get_effect( "STAMINA", reduced );
525 if( val != 0 ) {
526 mod = 1;
527 if( is_new || it.activated( calendar::turn, "STAMINA", val, reduced, mod ) ) {
529 it.get_max_val( "STAMINA", reduced ),
530 it.get_min_val( "STAMINA", reduced ) ) );
531 }
532 }
533
534 // Speed and stats are handled in recalc_speed_bonus and reset_stats respectively
535}
int bound_mod_to_vals(int val, int mod, int max, int min)
Clamp the value of a modifier in order to bound the resulting value.
static const trait_id trait_FAT("FAT")
virtual int get_healthy_mod() const
Definition: character.cpp:4169
void cough(bool harmful=false, int loudness=4)
Definition: character.cpp:7546
void hardcoded_effects(effect &it)
Handles the still hard-coded effects.
bool resists_effect(const effect &e) const
Returns true if the creature resists an effect.
Definition: creature.cpp:1350
bool get_sizing(const std::string &arg) const
Returns true if the given modifier type's trigger chance is affected by size mutations.
Definition: effect.cpp:1021
bool get_harmful_cough() const
Returns true if the coughs caused by an effect can harm the player directly.
Definition: effect.cpp:1199
int get_mod(std::string arg, bool reduced=false) const
Returns the matching modifier type from an effect, used for getting actual effect effects.
Definition: effect.cpp:910
int get_max_val(std::string arg, bool reduced=false) const
Returns the maximum value of a modifier type that get_mod() and get_amount() will push the player to.
Definition: effect.cpp:1006
double get_addict_mod(const std::string &arg, int addict_level) const
Returns the modifier caused by addictions.
Definition: effect.cpp:1185
std::vector< std::pair< std::string, int > > get_miss_msgs() const
Returns a vector of the miss message messages and chances for use in add_miss_reason() while the effe...
Definition: effect.cpp:1216
bool activated(const time_point &when, std::string arg, int val, bool reduced=false, double mod=1) const
Checks to see if a given modifier type can activate, and performs any rolls required to do so.
Definition: effect.cpp:1108
int get_min_val(std::string arg, bool reduced=false) const
Returns the minimum value of a modifier type that get_mod() and get_amount() will push the player to.
Definition: effect.cpp:991
void add_pain_msg(const Character &who, int val, body_part bp)
Add message describing how character feels pain.

References _, effect::activated(), add_miss_reason(), Creature::add_msg_if_player(), character_funcs::add_pain_msg(), addiction_level(), apply_damage(), arg(), body_part_name_accusative(), bound_mod_to_vals(), bp_torso, convert_bp(), cough(), efftype_id, fall_asleep(), time_duration::from_turns(), effect::get_addict_mod(), effect::get_amount(), effect::get_bp(), Creature::get_effect(), get_fatigue(), effect::get_harmful_cough(), get_healthy(), get_healthy_mod(), effect::get_max_val(), effect::get_min_val(), effect::get_miss_msgs(), effect::get_mod(), Creature::get_pain(), get_painkiller(), get_rad(), get_size(), effect::get_sizing(), get_stamina(), get_stim(), get_stored_kcal(), get_thirst(), hardcoded_effects(), Creature::has_effect(), has_trait(), in_sleep_state(), max_stored_kcal(), mod_fatigue(), mod_healthy(), mod_healthy_mod(), mod_pain(), mod_painkiller(), mod_rad(), mod_stamina(), mod_stim(), mod_stored_kcal(), mod_thirst(), MS_HUGE, MS_LARGE, num_bp, PKILLER, Creature::resists_effect(), set_rad(), body_part_type::token, trait_FAT, calendar::turn, vomit(), and character_effects::vomit_mod().

Referenced by process_effects_internal().

◆ process_turn()

void Character::process_turn ( )
overridevirtual

Handles end-of-turn processing.

Reimplemented from Creature.

Reimplemented in npc.

Definition at line 160 of file character_turn.cpp.

161{
162 // Has to happen before reset_stats
164
165 for( bionic &i : *my_bionics ) {
166 if( i.incapacitated_time > 0_turns ) {
167 i.incapacitated_time -= 1_turns;
168 if( i.incapacitated_time == 0_turns ) {
169 add_msg_if_player( m_bad, _( "Your %s bionic comes back online." ), i.info().name );
170 }
171 }
172 }
173
175
176 // If we're actively handling something we can't just drop it on the ground
177 // in the middle of handling it
178 if( activity.targets.empty() ) {
180 }
182 // Didn't just pick something up
183 last_item = itype_id( "null" );
184
185 visit_items( [this]( item * e ) {
186 e->process_artifact( as_player(), pos() );
187 e->process_relic( *this );
188 return VisitResponse::NEXT;
189 } );
190
191 suffer();
192
193 // Handle player and NPC morale ticks
194
195 if( calendar::once_every( 1_minutes ) ) {
197 }
198
199 if( calendar::once_every( 9_turns ) ) {
201 }
202
203 // NPCs currently don't make any use of their scent, pointless to calculate it
204 // TODO: make use of NPC scent.
205 if( !is_npc() ) {
208 }
209 const int mask_intensity = get_effect_int( effect_masked_scent );
210
211 // Set our scent towards the norm
212 int norm_scent = 500;
213 int temp_norm_scent = INT_MIN;
214 bool found_intensity = false;
215 for( const trait_id &mut : get_mutations() ) {
216 const std::optional<int> &scent_intensity = mut->scent_intensity;
217 if( scent_intensity ) {
218 found_intensity = true;
219 temp_norm_scent = std::max( temp_norm_scent, *scent_intensity );
220 }
221 }
222 if( found_intensity ) {
223 norm_scent = temp_norm_scent;
224 }
225
226 for( const trait_id &mut : get_mutations() ) {
227 const std::optional<int> &scent_mask = mut->scent_mask;
228 if( scent_mask ) {
229 norm_scent += *scent_mask;
230 }
231 }
232
233 //mask from scent altering items;
234 norm_scent += mask_intensity;
235
236 // Scent increases fast at first, and slows down as it approaches normal levels.
237 // Estimate it will take about norm_scent * 2 turns to go from 0 - norm_scent / 2
238 // Without smelly trait this is about 1.5 hrs. Slows down significantly after that.
239 if( scent < rng( 0, norm_scent ) ) {
240 scent++;
241 }
242
243 // Unusually high scent decreases steadily until it reaches normal levels.
244 if( scent > norm_scent ) {
245 scent--;
246 }
247
248 for( const trait_id &mut : get_mutations() ) {
249 scent *= mut.obj().scent_modifier;
250 }
251 }
252
253 // We can dodge again! Assuming we can actually move...
254 if( in_sleep_state() ) {
255 blocks_left = 0;
256 dodges_left = 0;
257 } else if( moves > 0 ) {
260 }
261
262 // auto-learning. This is here because skill-increases happens all over the place:
263 // SkillLevel::readBook (has no connection to the skill or the player),
264 // player::read, player::practice, ...
265 // Check for spontaneous discovery of martial art styles
266 for( auto &style : autolearn_martialart_types() ) {
267 const matype_id &ma( style );
268
269 if( !martial_arts_data->has_martialart( ma ) && can_autolearn_martial_art( *this, ma ) ) {
270 martial_arts_data->add_martialart( ma );
271 add_msg_if_player( m_info, _( "You have learned a new style: %s!" ), ma.obj().name );
272 }
273 }
274
275 // Update time spent conscious in this overmap tile for the Nomad traits.
276 if( !is_npc() && ( has_trait( trait_NOMAD ) || has_trait( trait_NOMAD2 ) ||
277 has_trait( trait_NOMAD3 ) ) &&
280 const point_abs_omt pos = ompos.xy();
281 if( overmap_time.find( pos ) == overmap_time.end() ) {
282 overmap_time[pos] = 1_turns;
283 } else {
284 overmap_time[pos] += 1_turns;
285 }
286 }
287 // Decay time spent in other overmap tiles.
288 if( !is_npc() && calendar::once_every( 1_hours ) ) {
290 const time_point now = calendar::turn;
291 time_duration decay_time = 0_days;
292 if( has_trait( trait_NOMAD ) ) {
293 decay_time = 7_days;
294 } else if( has_trait( trait_NOMAD2 ) ) {
295 decay_time = 14_days;
296 } else if( has_trait( trait_NOMAD3 ) ) {
297 decay_time = 28_days;
298 }
299 auto it = overmap_time.begin();
300 while( it != overmap_time.end() ) {
301 if( it->first == ompos.xy() ) {
302 it++;
303 continue;
304 }
305 // Find the amount of time passed since the player touched any of the overmap tile's submaps.
306 const tripoint_abs_omt tpt( it->first, 0 );
307 const time_point last_touched = overmap_buffer.scent_at( tpt ).creation_time;
308 const time_duration since_visit = now - last_touched;
309 // If the player has spent little time in this overmap tile, let it decay after just an hour instead of the usual extended decay time.
310 const time_duration modified_decay_time = it->second > 5_minutes ? decay_time : 1_hours;
311 if( since_visit > modified_decay_time ) {
312 // Reduce the tracked time spent in this overmap tile.
313 const time_duration decay_amount = std::min( since_visit - modified_decay_time, 1_hours );
314 const time_duration updated_value = it->second - decay_amount;
315 if( updated_value <= 0_turns ) {
316 // We can stop tracking this tile if there's no longer any time recorded there.
317 it = overmap_time.erase( it );
318 continue;
319 } else {
320 it->second = updated_value;
321 }
322 }
323 it++;
324 }
325 }
326}
static const efftype_id effect_narcosis("narcosis")
static const efftype_id effect_masked_scent("masked_scent")
static const trait_id trait_NOMAD2("NOMAD2")
static const trait_id trait_NOMAD3("NOMAD3")
static const trait_id trait_NOMAD("NOMAD")
static const efftype_id effect_sleep("sleep")
void update_morale()
Ticks down morale counters and removes them.
Definition: character.cpp:9002
void process_items()
Process active items.
void clear_miss_reasons()
Clears the list of reasons for why the player would miss a melee attack.
Definition: melee.cpp:384
void suffer()
Handles a large number of timers decrementing and other randomized effects.
Definition: suffer.cpp:1534
bool check_and_recover_morale()
Checks permanent morale for consistency and recovers it when an inconsistency is found.
Definition: character.cpp:9129
virtual void process_turn()
Processes effects and bonuses and allocates move points based on speed.
Definition: creature.cpp:153
virtual int get_num_dodges() const
Definition: creature.cpp:1484
virtual int get_num_blocks() const
Definition: creature.cpp:1480
void process_artifact(player *carrier, const tripoint &pos)
Process and apply artifact effects.
Definition: item.cpp:9090
void process_relic(Character &carrier)
Definition: item.cpp:9132
scent_trace scent_at(const tripoint_abs_omt &pos)
Method to retrieve the scent at a given location.
std::vector< item_location > targets
time_point creation_time
Definition: overmap_types.h:15
A point in the game time.
Definition: calendar.h:431
std::vector< matype_id > autolearn_martialart_types()
bool can_autolearn_martial_art(const Character &who, const matype_id &ma_id)
Returns true if the character can learn the entered martial art.

References _, activity, Creature::add_msg_if_player(), Creature::as_player(), autolearn_martialart_types(), blocks_left, can_autolearn_martial_art(), check_and_recover_morale(), clear_miss_reasons(), scent_trace::creation_time, dodges_left, drop_invalid_inventory(), effect_masked_scent, effect_narcosis, effect_sleep, Creature::get_effect_int(), get_mutations(), Creature::get_num_blocks(), Creature::get_num_dodges(), global_omt_location(), Creature::has_effect(), has_trait(), in_sleep_state(), Creature::is_npc(), itype_id, last_item, m_bad, m_info, martial_arts_data, Creature::moves, my_bionics, martialart::name, NEXT, string_id< T >::obj(), calendar::once_every(), overmap_buffer, overmap_time, pos(), item::process_artifact(), process_items(), item::process_relic(), Creature::process_turn(), restore_scent(), rng(), scent, overmapbuffer::scent_at(), suffer(), player_activity::targets, trait_NOMAD, trait_NOMAD2, trait_NOMAD3, calendar::turn, update_morale(), visitable< Character >::visit_items(), and coords::coord_point< Point, Origin, Scale >::xy().

Referenced by game::do_turn(), npc::process_turn(), and game::start_game().

◆ query_yn() [1/2]

template<typename ... Args>
bool Character::query_yn ( const char *const  msg,
Args &&...  args 
) const
inline

It is supposed to hide the query_yn to simplify player vs.

npc code.

Definition at line 1497 of file character.h.

1497 {
1498 return query_yn( string_format( msg, std::forward<Args>( args ) ... ) );
1499 }

References query_yn(), and string_format().

Referenced by activate_bionic(), can_install_bionics(), query_yn(), takeoff(), and will_eat().

◆ query_yn() [2/2]

virtual bool Character::query_yn ( const std::string &  msg) const
pure virtual

Implemented in npc, player, and player.

◆ ranged_dex_mod()

int Character::ranged_dex_mod ( ) const
virtual
Dexterity <20 increases ranged penalty

Definition at line 4153 of file character.cpp.

4154{
4155 ///\EFFECT_DEX <20 increases ranged penalty
4156 return std::max( ( 20.0 - get_dex() ) * 0.5, 0.0 );
4157}

References get_dex().

Referenced by draw_stats_info(), ranged::get_weapon_dispersion(), and set_stats().

◆ ranged_per_mod()

int Character::ranged_per_mod ( ) const
virtual
Perception <20 increases ranged aiming penalty.

Definition at line 4159 of file character.cpp.

4160{
4161 ///\EFFECT_PER <20 increases ranged aiming penalty.
4162 return std::max( ( 20.0 - get_per() ) * 1.2, 0.0 );
4163}

References get_per().

Referenced by draw_stats_info(), ranged::effective_dispersion(), and set_stats().

◆ reach_attack()

void Character::reach_attack ( const tripoint p)

Handles reach melee attack on point p.

Melee >5 allows WHIP_DISARM technique Stabbing decreases chance of hitting intervening target on reach attack Stabbing increases ability to reach attack through fences Strength increases bash effects when reach attacking past something

Definition at line 677 of file melee.cpp.

678{
679 matec_id force_technique = tec_none;
680 /** @EFFECT_MELEE >5 allows WHIP_DISARM technique */
681 if( primary_weapon().has_flag( "WHIP" ) && ( get_skill_level( skill_melee ) > 5 ) && one_in( 3 ) ) {
682 force_technique = matec_id( "WHIP_DISARM" );
683 }
684
685 map &here = get_map();
686 Creature *critter = g->critter_at( p );
687 // Original target size, used when there are monsters in front of our target
688 int target_size = critter != nullptr ? ( critter->get_size() + 1 ) : 2;
689 // Reset last target pos
690 as_player()->last_target_pos = std::nullopt;
691 // Max out recoil
693
695 int skill = std::min( 10, get_skill_level( skill_stabbing ) );
696 int t = 0;
697 std::vector<tripoint> path = line_to( pos(), p, t, 0 );
698 tripoint last_point = pos();
699 path.pop_back(); // Last point is our critter
700 for( const tripoint &path_point : path ) {
701 // Possibly hit some unintended target instead
702 Creature *inter = g->critter_at( path_point );
703 int inter_block_size = inter != nullptr ? ( inter->get_size() + 1 ) : 2;
704 /** @EFFECT_STABBING decreases chance of hitting intervening target on reach attack */
705 if( inter != nullptr &&
706 !x_in_y( ( target_size * target_size + 1 ) * skill,
707 ( inter_block_size * inter_block_size + 1 ) * 10 ) ) {
708 // Even if we miss here, low roll means weapon is pushed away or something like that
709 critter = inter;
710 break;
711 } else if( here.obstructed_by_vehicle_rotation( last_point, path_point ) ) {
712 tripoint rand = path_point;
713 if( one_in( 2 ) ) {
714 rand.x = last_point.x;
715 } else {
716 rand.y = last_point.y;
717 }
718
719 here.bash( rand, str_cur + primary_weapon().damage_melee( DT_BASH ) );
722 return;
723 /** @EFFECT_STABBING increases ability to reach attack through fences */
724 } else if( here.impassable( path_point ) &&
725 // Fences etc. Spears can stab through those
726 !( primary_weapon().has_flag( "SPEAR" ) &&
727 g->m.has_flag( "THIN_OBSTACLE", path_point ) &&
728 x_in_y( skill, 10 ) ) ) {
729 /** @EFFECT_STR increases bash effects when reach attacking past something */
730 here.bash( path_point, str_cur + primary_weapon().damage_melee( DT_BASH ) );
733 return;
734 }
735 last_point = path_point;
736 }
737
738 if( here.obstructed_by_vehicle_rotation( last_point, p ) ) {
739 tripoint rand = p;
740 if( one_in( 2 ) ) {
741 rand.x = last_point.x;
742 } else {
743 rand.y = last_point.y;
744 }
745
746 here.bash( rand, str_cur + primary_weapon().damage_melee( DT_BASH ) );
749 return;
750 }
751
752 if( critter == nullptr ) {
753 add_msg_if_player( _( "You swing at the air." ) );
754 if( martial_arts_data->has_miss_recovery_tec( primary_weapon() ) ) {
755 move_cost /= 3; // "Probing" is faster than a regular miss
756 }
757
759 return;
760 }
761
762 reach_attacking = true;
763 melee_attack( *critter, false, &force_technique, false );
764 reach_attacking = false;
765}
virtual m_size get_size() const =0
bool obstructed_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.
Definition: map.cpp:6622
bool impassable(const tripoint &p) const
Definition: map.cpp:1859
std::optional< tripoint > last_target_pos
Definition: player.h:242
static const skill_id skill_stabbing("stabbing")
string_id< ma_technique > matec_id
Definition: type_id.h:92

References _, Creature::add_msg_if_player(), Creature::as_player(), attack_cost(), map::bash(), item::damage_melee(), DT_BASH, g, get_map(), Creature::get_size(), get_skill_level(), handle_melee_wear(), Creature::has_flag(), map::impassable(), player::last_target_pos, line_to(), martial_arts_data, MAX_RECOIL, melee_attack(), Creature::mod_moves(), move_cost(), map::obstructed_by_vehicle_rotation(), one_in(), pos(), primary_weapon(), reach_attacking, recoil, skill_melee, skill_stabbing, str_cur, tec_none, tripoint::x, x_in_y(), and tripoint::y.

Referenced by npc::execute_action(), and reach_attack().

◆ react_to_felt_pain()

void Character::react_to_felt_pain ( int  intensity)

Definition at line 740 of file character.cpp.

741{
742 if( intensity <= 0 ) {
743 return;
744 }
745 if( is_player() && intensity >= 2 ) {
746 g->cancel_activity_or_ignore_query( distraction_type::pain, _( "Ouch, something hurts!" ) );
747 }
748 // Only a large pain burst will actually wake people while sleeping.
750 int pain_thresh = rng( 3, 5 );
751
753 pain_thresh += 2;
754 } else if( has_trait( trait_HEAVYSLEEPER2 ) ) {
755 pain_thresh += 5;
756 }
757
758 if( intensity >= pain_thresh ) {
759 wake_up();
760 }
761 }
762}
static const trait_id trait_HEAVYSLEEPER("HEAVYSLEEPER")
static const trait_id trait_HEAVYSLEEPER2("HEAVYSLEEPER2")

References _, effect_narcosis, effect_sleep, g, Creature::has_effect(), has_trait(), Creature::is_player(), pain, rng(), trait_HEAVYSLEEPER, trait_HEAVYSLEEPER2, and wake_up().

Referenced by set_pain(), and set_painkiller().

◆ read_speed()

int Character::read_speed ( bool  return_stat_effect = true) const

Returns the player's reading speed.

Intelligence increases reading speed by 3s per level above 8

Definition at line 3500 of file character.cpp.

3501{
3502 // Stat window shows stat effects on based on current stat
3503 const int intel = get_int();
3504 /** @EFFECT_INT increases reading speed by 3s per level above 8*/
3505 int ret = to_moves<int>( 1_minutes ) - to_moves<int>( 3_seconds ) * ( intel - 8 );
3506
3508 ret *= .75;
3509 }
3510
3511 ret *= mutation_value( "reading_speed_multiplier" );
3512
3513 if( ret < to_moves<int>( 1_seconds ) ) {
3514 ret = to_moves<int>( 1_seconds );
3515 }
3516 // return_stat_effect actually matters here
3517 return return_stat_effect ? ret : ret * 100 / to_moves<int>( 1_minutes );
3518}
static const bionic_id afs_bio_linguistic_coprocessor("afs_bio_linguistic_coprocessor")

References afs_bio_linguistic_coprocessor, get_int(), has_bionic(), mutation_value(), and cata::hash64_detail::ret.

Referenced by draw_stats_info(), read_inventory_preset::read_inventory_preset(), set_stats(), npc::time_to_read(), and avatar::time_to_read().

◆ rebuild_mutation_cache()

void Character::rebuild_mutation_cache ( )

Definition at line 7897 of file character.cpp.

7898{
7899 cached_mutations.clear();
7900 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
7901 cached_mutations.push_back( &mut.first.obj() );
7902 }
7903 for( const trait_id &mut : enchantment_cache->get_mutations() ) {
7904 cached_mutations.push_back( &mut.obj() );
7905 }
7906}

References cached_mutations, enchantment_cache, and my_mutations.

Referenced by set_mutation(), and unset_mutation().

◆ recalc_hp()

void Character::recalc_hp ( )

Recalculates HP after a change to max strength.

Definition at line 1582 of file character.cpp.

1583{
1584 int str_boost_val = 0;
1585 std::optional<skill_boost> str_boost = skill_boost::get( "str" );
1586 if( str_boost ) {
1587 int skill_total = 0;
1588 for( const std::string &skill_str : str_boost->skills() ) {
1589 skill_total += get_skill_level( skill_id( skill_str ) );
1590 }
1591 str_boost_val = str_boost->calc_bonus( skill_total );
1592 }
1593 // Mutated toughness stacks with starting, by design.
1594 float hp_mod = 1.0f + mutation_value( "hp_modifier" ) + mutation_value( "hp_modifier_secondary" );
1595 float hp_adjustment = mutation_value( "hp_adjustment" ) + ( str_boost_val * 3 );
1596 calc_all_parts_hp( hp_mod, hp_adjustment, get_str_base() );
1597}
void calc_all_parts_hp(float hp_mod=0.0, float hp_adjust=0.0, int str_max=0)
Sets hp for all body parts.
Definition: character.cpp:1599
static std::optional< skill_boost > get(const std::string &stat_str)
Definition: skill_boost.cpp:20

References calc_all_parts_hp(), skill_boost::get(), get_skill_level(), get_str_base(), mutation_value(), and skill_id.

Referenced by apply_mods(), apply_skill_boost(), avatar::create(), mutation_effect(), mutation_loss_effect(), character_funcs::normalize(), npc::randomize(), reset_scenario(), set_stats(), standard_npc::standard_npc(), and avatar::upgrade_stat().

◆ recalc_sight_limits()

void Character::recalc_sight_limits ( )

Modifies the player's sight values Must be called when any of the following change: This must be called when any of the following change:

  • effects
  • bionics
  • traits
  • underwater
  • clothes

Definition at line 1629 of file character.cpp.

1630{
1631 sight_max = 9999;
1632 vision_mode_cache.reset();
1633
1634 // Set sight_max.
1635 if( is_blind() || ( in_sleep_state() && !has_trait( trait_SEESLEEP ) ) ||
1637 sight_max = 0;
1638 } else if( has_effect( effect_boomered ) && ( !( has_trait( trait_PER_SLIME_OK ) ) ) ) {
1639 sight_max = 1;
1641 } else if( has_effect( effect_in_pit ) || has_effect( effect_no_sight ) ||
1645 sight_max = 1;
1646 } else if( has_active_mutation( trait_SHELL2 ) ) {
1647 // You can kinda see out a bit.
1648 sight_max = 2;
1649 } else if( ( has_trait( trait_MYOPIC ) || has_trait( trait_URSINE_EYE ) ) &&
1651 sight_max = 4;
1652 } else if( has_trait( trait_PER_SLIME ) ) {
1653 sight_max = 6;
1654 } else if( has_effect( effect_darkness ) ) {
1656 sight_max = 10;
1657 }
1658
1659 // Debug-only NV
1662 }
1663
1664 float best_bonus_nv = 0.0f;
1665 for( const mutation_branch *mut : cached_mutations ) {
1666 best_bonus_nv = std::max( best_bonus_nv, mut->night_vision_range );
1667 }
1669 ( is_mounted() && mounted_creature->has_flag( MF_MECH_RECON_VISION ) ) ) {
1670 best_bonus_nv = std::max( best_bonus_nv, 10.0f );
1671 }
1672 if( has_nv() ) {
1674 best_bonus_nv = std::max( best_bonus_nv, 10.0f );
1675 }
1676 if( has_trait( trait_BIRD_EYE ) ) {
1678 }
1679 if( has_trait( trait_URSINE_EYE ) ) {
1681 }
1682
1683 // +1 because of the ugly -1 in _from_per
1686 nv_range += best_bonus_nv;
1688 nv_range++;
1689 }
1690
1691 // Not exactly a sight limit thing, but related enough
1696 mounted_creature->has_flag( MF_MECH_RECON_VISION ) ) ) {
1698 }
1699
1701 has_effect_with_flag( "EFFECT_SUPER_CLAIRVOYANCE" ) ) {
1704 has_effect_with_flag( "EFFECT_CLAIRVOYANCE_PLUS" ) ) {
1706 } else if( has_artifact_with( AEP_CLAIRVOYANCE ) ||
1707 has_effect_with_flag( "EFFECT_CLAIRVOYANCE" ) ) {
1709 }
1710}
static const bionic_id bio_infrared("bio_infrared")
static const std::string flag_FIX_NEARSIGHT("FIX_NEARSIGHT")
static const efftype_id effect_contacts("contacts")
static const trait_id trait_CEPH_EYES("CEPH_EYES")
static const trait_id trait_INFRARED("INFRARED")
static const trait_id trait_LIZ_IR("LIZ_IR")
static const trait_id trait_URSINE_EYE("URSINE_EYE")
static const trait_id trait_MEMBRANE("MEMBRANE")
static const trait_id trait_MYOPIC("MYOPIC")
static const trait_id trait_BIRD_EYE("BIRD_EYE")
static const efftype_id effect_darkness("darkness")
static const bionic_id bio_membrane("bio_membrane")
static const std::string flag_SWIM_GOGGLES("SWIM_GOGGLES")
static const std::string flag_IR_EFFECT("IR_EFFECT")
static const trait_id trait_DEBUG_NIGHTVISION("DEBUG_NIGHTVISION")
static const trait_id trait_PER_SLIME_OK("PER_SLIME_OK")
static const efftype_id effect_no_sight("no_sight")
bool has_nv()
Returns true if the player has some form of night vision.
Definition: character.cpp:3652
int sight_max
Definition: character.h:2185
@ AEP_CLAIRVOYANCE_PLUS
Definition: enums.h:142
@ AEP_SUPER_CLAIRVOYANCE
Definition: enums.h:112
@ AEP_CLAIRVOYANCE
Definition: enums.h:111
float nv_range_from_per(int per)
Definition: character.cpp:1722
float nv_range_from_eye_encumbrance(int enc)
Definition: character.cpp:1728

References AEP_CLAIRVOYANCE, AEP_CLAIRVOYANCE_PLUS, AEP_SUPER_CLAIRVOYANCE, bio_infrared, bio_membrane, BIRD_EYE, BOOMERED, bp_eyes, cached_mutations, DARKNESS, DEBUG_NIGHTVISION, effect_boomered, effect_contacts, effect_darkness, effect_in_pit, effect_narcosis, effect_no_sight, encumb(), flag_FIX_NEARSIGHT(), flag_IR_EFFECT(), flag_SWIM_GOGGLES(), get_per(), has_active_bionic(), has_active_mutation(), has_artifact_with(), has_bionic(), Creature::has_effect(), Creature::has_effect_with_flag(), has_nv(), has_trait(), in_sleep_state(), IR_VISION, is_blind(), is_mounted(), Creature::is_underwater(), is_wearing(), itype_rm13_armor_on, MF_MECH_RECON_VISION, mounted_creature, NV_GOGGLES, nv_range, vision::nv_range_from_eye_encumbrance(), vision::nv_range_from_per(), sight_max, trait_BIRD_EYE, trait_CEPH_EYES, trait_DEBUG_NIGHTVISION, trait_INFRARED, trait_LIZ_IR, trait_MEMBRANE, trait_MYOPIC, trait_PER_SLIME, trait_PER_SLIME_OK, trait_SEESLEEP, trait_SHELL2, trait_URSINE_EYE, URSINE_VISION, VISION_CLAIRVOYANCE, VISION_CLAIRVOYANCE_PLUS, VISION_CLAIRVOYANCE_SUPER, vision_mode_cache, and worn_with_flag().

Referenced by add_bionic(), deactivate_mutation(), environmental_revert_effect(), load(), game::load(), mount_creature(), mutation_spend_resources(), on_item_takeoff(), on_item_wear(), player::player(), remove_bionic(), reset_stats(), set_mutation(), set_underwater(), takeoff(), unset_mutation(), wake_up(), and wear_item().

◆ recalc_speed_bonus()

void Character::recalc_speed_bonus ( )

Calculates the various speed bonuses we will get from mutations, etc.

Definition at line 94 of file character_turn.cpp.

95{
96 // Minus some for weight...
97 int carry_penalty = 0;
98 if( weight_carried() > weight_capacity() && !has_trait( trait_id( "DEBUG_STORAGE" ) ) ) {
99 carry_penalty = 25 * ( weight_carried() - weight_capacity() ) / ( weight_capacity() );
100 }
101 mod_speed_bonus( -carry_penalty );
102
104
107 }
108 // when underweight, you get slower. cumulative with hunger
110
111 for( const auto &maps : *effects ) {
112 for( auto &i : maps.second ) {
113 if( i.second.is_removed() ) {
114 continue;
115 }
116 bool reduced = resists_effect( i.second );
117 mod_speed_bonus( i.second.get_mod( "SPEED", reduced ) );
118 }
119 }
120
121 // add martial arts speed bonus
123
124 // Not sure why Sunlight Dependent is here, but OK
125 // Ectothermic/COLDBLOOD4 is intended to buff folks in the Summer
126 // Threshold-crossing has its charms ;-)
127 if( g != nullptr ) {
128 if( has_trait( trait_SUNLIGHT_DEPENDENT ) && !g->is_in_sunlight( pos() ) ) {
129 mod_speed_bonus( -( g->light_level( posz() ) >= 12 ? 5 : 10 ) );
130 }
131 const float temperature_speed_modifier = mutation_value( "temperature_speed_modifier" );
132 if( temperature_speed_modifier != 0 ) {
133 const auto player_local_temp = get_weather().get_temperature( pos() );
134 if( has_trait( trait_COLDBLOOD4 ) || player_local_temp < 65 ) {
135 mod_speed_bonus( ( player_local_temp - 65 ) * temperature_speed_modifier );
136 }
137 }
138 }
139
141 mod_speed_bonus( 20 );
142 }
144 mod_speed_bonus( -20 );
145 }
146
148
149 float speed_modifier = Character::mutation_value( "speed_modifier" );
150 mod_speed_mult( speed_modifier - 1 );
151
152 if( has_bionic( bio_speed ) ) { // add 10% speed bonus
153 mod_speed_mult( 0.1 );
154 }
155
156 double ench_bonus = enchantment_cache->calc_bonus( enchant_vals::mod::SPEED, get_speed() );
157 mod_speed_bonus( ench_bonus );
158}
int get_speedydex_bonus(const int dex)
Returns value of speedydex bonus if enabled.
Definition: character.cpp:4139
static const trait_id trait_COLDBLOOD4("COLDBLOOD4")
static const trait_id trait_SUNLIGHT_DEPENDENT("SUNLIGHT_DEPENDENT")
static const bionic_id bio_speed("bio_speed")
int mabuff_speed_bonus() const
Returns the speed bonus from martial arts buffs.
virtual void mod_speed_mult(float nspeed)
Definition: creature.cpp:1816
virtual void mod_speed_bonus(int nspeed)
Definition: creature.cpp:1812
@ AEP_SPEED_UP
Definition: enums.h:107
@ AEP_SPEED_DOWN
Definition: enums.h:137
int get_thirst_speed_penalty(int thirst)
Returns the penalty to speed from thirst.
int get_kcal_speed_penalty(float kcal_percent)
Returns the penalty to speed from starvation.
stat_mod get_pain_penalty(const Character &ch)
Returns the effect of pain on stats.

References AEP_SPEED_DOWN, AEP_SPEED_UP, bio_speed, Creature::effects, enchantment_cache, g, get_dex(), get_kcal_percent(), character_effects::get_kcal_speed_penalty(), character_effects::get_pain_penalty(), get_speed(), get_speedydex_bonus(), weather_manager::get_temperature(), get_thirst(), character_effects::get_thirst_speed_penalty(), get_weather(), has_artifact_with(), has_bionic(), has_trait(), mabuff_speed_bonus(), Creature::mod_speed_bonus(), Creature::mod_speed_mult(), mutation_value(), pos(), posz(), Creature::resists_effect(), stat_mod::speed, enchant_vals::SPEED, trait_COLDBLOOD4, trait_id, trait_SUNLIGHT_DEPENDENT, very_thirsty, weight_capacity(), and weight_carried().

Referenced by reset_stats().

◆ recalculate_enchantment_cache()

void Character::recalculate_enchantment_cache ( )

Definition at line 7856 of file character.cpp.

7857{
7858 // start by resetting the cache
7860
7861 visit_items( [&]( const item * it ) {
7862 for( const enchantment &ench : it->get_enchantments() ) {
7863 if( ench.is_active( *this, *it ) ) {
7864 enchantment_cache->force_add( ench );
7865 }
7866 }
7867 return VisitResponse::NEXT;
7868 } );
7869
7870 // get from traits/ mutations
7871 for( const std::pair<const trait_id, char_trait_data> &mut_map : my_mutations ) {
7872 const mutation_branch &mut = mut_map.first.obj();
7873
7874 for( const enchantment_id &ench_id : mut.enchantments ) {
7875 const enchantment &ench = ench_id.obj();
7876 if( ench.is_active( *this, mut.activated && mut_map.second.powered ) ) {
7877 enchantment_cache->force_add( ench );
7878 }
7879 }
7880 }
7881
7882 for( const bionic &bio : *my_bionics ) {
7883 const bionic_id &bid = bio.id;
7884
7885 for( const enchantment_id &ench_id : bid->enchantments ) {
7886 const enchantment &ench = ench_id.obj();
7887 if( ench.is_active( *this, bio.powered &&
7888 bid->has_flag( STATIC( flag_str_id( "BIONIC_TOGGLED" ) ) ) ) ) {
7889 enchantment_cache->force_add( ench );
7890 }
7891 }
7892 }
7893
7895}
void rebuild_mutation_cache()
Definition: character.cpp:7897
bool is_active(const Character &guy, const item &parent) const
const std::vector< enchantment > & get_enchantments() const
Definition: item.cpp:7003
bool activated
Definition: mutation.h:93

References enchantment_cache, item::get_enchantments(), NEXT, and visitable< Character >::visit_items().

Referenced by activate_bionic(), activate_mutation(), add_bionic(), deactivate_bionic(), deactivate_mutation(), on_mutation_gain(), on_mutation_loss(), remove_bionic(), reset(), update_body(), and avatar_funcs::use_item().

◆ recalculate_size()

void Character::recalculate_size ( )

Recalculate size class of character.

Definition at line 244 of file mutation.cpp.

245{
247 // Only one size-changing mutation is expected, so it will only use the first one it finds.
248 for( const mutation_branch *mut : cached_mutations ) {
249 if( mut->body_size ) {
250 size_class = *mut->body_size;
251 break;
252 }
253 }
254}

References cached_mutations, MS_MEDIUM, and size_class.

Referenced by load(), mutation_effect(), and mutation_loss_effect().

◆ reduce_healing_effect()

int Character::reduce_healing_effect ( const efftype_id eff_id,
int  remove_med,
const bodypart_id hurt 
)

Reduce healing effect intensity, return initial intensity of the effect.

Definition at line 8621 of file character.cpp.

8623{
8624 const body_part hurt_token = hurt->token;
8625 effect &e = get_effect( eff_id, hurt_token );
8626 int intensity = e.get_intensity();
8627 if( remove_med < intensity ) {
8628 if( eff_id == effect_bandaged ) {
8629 add_msg_if_player( m_bad, _( "Bandages on your %s were damaged!" ), body_part_name( hurt_token ) );
8630 } else if( eff_id == effect_disinfected ) {
8631 add_msg_if_player( m_bad, _( "You got some filth on your disinfected %s!" ),
8632 body_part_name( hurt_token ) );
8633 }
8634 } else {
8635 if( eff_id == effect_bandaged ) {
8636 add_msg_if_player( m_bad, _( "Bandages on your %s were destroyed!" ),
8637 body_part_name( hurt_token ) );
8638 } else if( eff_id == effect_disinfected ) {
8639 add_msg_if_player( m_bad, _( "Your %s is no longer disinfected!" ), body_part_name( hurt_token ) );
8640 }
8641 }
8642 e.mod_duration( -6_hours * remove_med );
8643 return intensity;
8644}

References _, Creature::add_msg_if_player(), body_part_name(), effect_bandaged, effect_disinfected, Creature::get_effect(), effect::get_intensity(), m_bad, and effect::mod_duration().

Referenced by apply_damage().

◆ regen()

void Character::regen ( int  rate_multiplier)

Handles passive regeneration of pain and maybe hp.

Definition at line 4572 of file character.cpp.

4573{
4574 int pain_ticks = rate_multiplier;
4575 while( get_pain() > 0 && pain_ticks-- > 0 ) {
4576 mod_pain( -roll_remainder( ( 0.2f + get_pain() / 50.0f ) * ( 1.0f +
4577 mutation_value( "pain_recovery" ) ) ) );
4578 }
4579
4580 float rest = rest_quality();
4581 float heal_rate = healing_rate( rest ) * to_turns<int>( 5_minutes );
4582 if( heal_rate > 0.0f ) {
4583 healall( roll_remainder( rate_multiplier * heal_rate ) );
4584 } else if( heal_rate < 0.0f ) {
4585 int rot_rate = roll_remainder( rate_multiplier * -heal_rate );
4586 // Has to be in loop because some effects depend on rounding
4587 while( rot_rate-- > 0 ) {
4588 hurtall( 1, nullptr, false );
4589 }
4590 }
4591
4592 // include healing effects
4593 for( int i = 0; i < num_hp_parts; i++ ) {
4594 const bodypart_id &bp = convert_bp( hp_to_bp( static_cast<hp_part>( i ) ) ).id();
4595 float healing = healing_rate_medicine( rest, bp ) * to_turns<int>( 5_minutes );
4596
4597 int healing_apply = roll_remainder( healing );
4598 healed_bp( i, healing_apply );
4599 heal( bp, healing_apply );
4600 if( damage_bandaged[i] > 0 ) {
4601 damage_bandaged[i] -= healing_apply;
4602 if( damage_bandaged[i] <= 0 ) {
4603 damage_bandaged[i] = 0;
4604 remove_effect( effect_bandaged, bp->token );
4605 add_msg_if_player( _( "Bandaged wounds on your %s healed." ), body_part_name( bp ) );
4606 }
4607 }
4608 if( damage_disinfected[i] > 0 ) {
4609 damage_disinfected[i] -= healing_apply;
4610 if( damage_disinfected[i] <= 0 ) {
4611 damage_disinfected[i] = 0;
4612 remove_effect( effect_disinfected, bp->token );
4613 add_msg_if_player( _( "Disinfected wounds on your %s healed." ), body_part_name( bp ) );
4614 }
4615 }
4616
4617 // remove effects if the limb was healed by other way
4618 if( has_effect( effect_bandaged, bp->token ) && ( get_part( bp ).is_at_max_hp() ) ) {
4619 damage_bandaged[i] = 0;
4620 remove_effect( effect_bandaged, bp->token );
4621 add_msg_if_player( _( "Bandaged wounds on your %s healed." ), body_part_name( bp ) );
4622 }
4623 if( has_effect( effect_disinfected, bp->token ) && ( get_part( bp ).is_at_max_hp() ) ) {
4624 damage_disinfected[i] = 0;
4625 remove_effect( effect_disinfected, bp->token );
4626 add_msg_if_player( _( "Disinfected wounds on your %s healed." ), body_part_name( bp ) );
4627 }
4628 }
4629
4630 if( get_rad() > 0 ) {
4631 mod_rad( -roll_remainder( rate_multiplier / 50.0f ) );
4632 }
4633}
float healing_rate(float at_rest_quality) const
Average hit points healed per turn.
Definition: character.cpp:6656
float healing_rate_medicine(float at_rest_quality, const bodypart_id &bp) const
Average hit points healed per turn from healing effects.
Definition: character.cpp:6698
void healed_bp(int bp, int amount)
Definition: character.cpp:7744

References _, Creature::add_msg_if_player(), body_part_name(), convert_bp(), damage_bandaged, damage_disinfected, effect_bandaged, effect_disinfected, Creature::get_pain(), Creature::get_part(), get_rad(), Creature::has_effect(), heal(), healall(), healed_bp(), healing_rate(), healing_rate_medicine(), hp_to_bp(), hurtall(), string_id< T >::id(), mod_pain(), mod_rad(), mutation_value(), num_hp_parts, Creature::remove_effect(), rest_quality(), and roll_remainder().

Referenced by update_body().

◆ rem_addiction()

void Character::rem_addiction ( add_type  type)

Removes an addition from the player.

Definition at line 2015 of file suffer.cpp.

2016{
2017 auto iter = std::find_if( addictions.begin(), addictions.end(),
2018 [type]( const addiction & ad ) {
2019 return ad.type == type;
2020 } );
2021
2022 if( iter != addictions.end() ) {
2023 addictions.erase( iter );
2024 g->events().send<event_type::loses_addiction>( getID(), type );
2025 }
2026}

References addictions, g, getID(), loses_addiction, and type.

Referenced by marloss_common(), iuse::mycus(), and suffer_from_addictions().

◆ rem_morale()

void Character::rem_morale ( const morale_type type)

◆ remove_bionic()

void Character::remove_bionic ( const bionic_id b)

Removes a bionic from my_bionics[].

Definition at line 2657 of file bionics.cpp.

2658{
2659 bionic_collection new_my_bionics;
2660 // any spells you should not forget due to still having a bionic installed that has it.
2661 std::set<spell_id> cbm_spells;
2662 for( bionic &i : *my_bionics ) {
2663 if( b == i.id ) {
2664 continue;
2665 }
2666
2667 // Linked bionics: if either is removed, the other is removed as well.
2668 if( b->is_included( i.id ) || i.id->is_included( b ) ) {
2669 continue;
2670 }
2671
2672 for( const std::pair<const spell_id, int> &spell_pair : i.id->learned_spells ) {
2673 cbm_spells.emplace( spell_pair.first );
2674 }
2675
2676 new_my_bionics.push_back( bionic( i.id, i.invlet ) );
2677 }
2678
2679 // any spells you learn from installing a bionic you forget.
2680 for( const std::pair<const spell_id, int> &spell_pair : b->learned_spells ) {
2681 if( cbm_spells.count( spell_pair.first ) == 0 ) {
2682 magic->forget_spell( spell_pair.first );
2683 }
2684 }
2685
2686 *my_bionics = new_my_bionics;
2689 if( !b->enchantments.empty() ) {
2691 }
2692}

References b, magic, my_bionics, recalc_sight_limits(), recalculate_enchantment_cache(), and reset_encumbrance().

Referenced by perform_install(), perform_uninstall(), and uninstall_bionic().

◆ remove_child_flag()

void Character::remove_child_flag ( const trait_id flag)

Removes the mutation's child flag from the player's list.

Definition at line 1471 of file mutation.cpp.

1472{
1473 for( auto &elem : flag->replacements ) {
1474 const trait_id &tmp = elem;
1475 if( has_trait( tmp ) ) {
1476 remove_mutation( tmp );
1477 return;
1478 } else if( has_child_flag( tmp ) ) {
1479 remove_child_flag( tmp );
1480 return;
1481 }
1482 }
1483}

References has_child_flag(), has_trait(), remove_child_flag(), remove_mutation(), and mutation_branch::replacements.

Referenced by mutate_towards(), and remove_child_flag().

◆ remove_mission_items()

void Character::remove_mission_items ( int  mission_id)

Definition at line 2529 of file character.cpp.

2530{
2531 if( mission_id == -1 ) {
2532 return;
2533 }
2534 remove_items_with( has_mission_item_filter { mission_id } );
2535}

References visitable< Character >::remove_items_with().

◆ remove_mutation()

void Character::remove_mutation ( const trait_id mut,
bool  silent = false 
)

Removes a mutation, downgrading to the previous level if possible.

Definition at line 1313 of file mutation.cpp.

1314{
1315 const auto &mdata = mut.obj();
1316 // Check if there's a prerequisite we should shrink back into
1317 trait_id replacing = trait_id::NULL_ID();
1318 std::vector<trait_id> originals = mdata.prereqs;
1319 for( size_t i = 0; !replacing && i < originals.size(); i++ ) {
1320 trait_id pre = originals[i];
1321 const auto &p = pre.obj();
1322 for( size_t j = 0; !replacing && j < p.replacements.size(); j++ ) {
1323 if( p.replacements[j] == mut ) {
1324 replacing = pre;
1325 }
1326 }
1327 }
1328
1329 trait_id replacing2 = trait_id::NULL_ID();
1330 std::vector<trait_id> originals2 = mdata.prereqs2;
1331 for( size_t i = 0; !replacing2 && i < originals2.size(); i++ ) {
1332 trait_id pre2 = originals2[i];
1333 const auto &p = pre2.obj();
1334 for( size_t j = 0; !replacing2 && j < p.replacements.size(); j++ ) {
1335 if( p.replacements[j] == mut ) {
1336 replacing2 = pre2;
1337 }
1338 }
1339 }
1340
1341 // See if this mutation is canceled by a base trait
1342 //Only if there's no prerequisite to shrink to, thus we're at the bottom of the trait line
1343 if( !replacing ) {
1344 //Check each mutation until we reach the end or find a trait to revert to
1345 for( auto &iter : mutation_branch::get_all() ) {
1346 //See if it's in our list of base traits but not active
1347 if( has_base_trait( iter.id ) && !has_trait( iter.id ) ) {
1348 //See if that base trait cancels the mutation we are using
1349 std::vector<trait_id> traitcheck = iter.cancels;
1350 if( !traitcheck.empty() ) {
1351 for( size_t j = 0; !replacing && j < traitcheck.size(); j++ ) {
1352 if( traitcheck[j] == mut ) {
1353 replacing = ( iter.id );
1354 }
1355 }
1356 }
1357 }
1358 if( replacing ) {
1359 break;
1360 }
1361 }
1362 }
1363
1364 // Duplicated for prereq2
1365 if( !replacing2 ) {
1366 //Check each mutation until we reach the end or find a trait to revert to
1367 for( auto &iter : mutation_branch::get_all() ) {
1368 //See if it's in our list of base traits but not active
1369 if( has_base_trait( iter.id ) && !has_trait( iter.id ) ) {
1370 //See if that base trait cancels the mutation we are using
1371 std::vector<trait_id> traitcheck = iter.cancels;
1372 if( !traitcheck.empty() ) {
1373 for( size_t j = 0; !replacing2 && j < traitcheck.size(); j++ ) {
1374 if( traitcheck[j] == mut && ( iter.id ) != replacing ) {
1375 replacing2 = ( iter.id );
1376 }
1377 }
1378 }
1379 }
1380 if( replacing2 ) {
1381 break;
1382 }
1383 }
1384 }
1385
1386 // make sure we don't toggle a mutation or trait twice, or it will cancel itself out.
1387 if( replacing == replacing2 ) {
1388 replacing2 = trait_id::NULL_ID();
1389 }
1390
1391 // This should revert back to a removed base trait rather than simply removing the mutation
1392 unset_mutation( mut );
1393
1394 bool mutation_replaced = false;
1395
1396 game_message_type rating;
1397
1398 if( replacing ) {
1399 const auto &replace_mdata = replacing.obj();
1400 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1401 rating = m_mixed;
1402 } else if( replace_mdata.points - mdata.points > 0 ) {
1403 rating = m_good;
1404 } else if( mdata.points - replace_mdata.points > 0 ) {
1405 rating = m_bad;
1406 } else {
1407 rating = m_neutral;
1408 }
1409 if( !silent ) {
1410 add_msg_player_or_npc( rating,
1411 _( "Your %1$s mutation turns into %2$s." ),
1412 _( "<npcname>'s %1$s mutation turns into %2$s." ),
1413 mdata.name(), replace_mdata.name() );
1414 }
1415 set_mutation( replacing );
1416 mutation_replaced = true;
1417 }
1418 if( replacing2 ) {
1419 const auto &replace_mdata = replacing2.obj();
1420 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1421 rating = m_mixed;
1422 } else if( replace_mdata.points - mdata.points > 0 ) {
1423 rating = m_good;
1424 } else if( mdata.points - replace_mdata.points > 0 ) {
1425 rating = m_bad;
1426 } else {
1427 rating = m_neutral;
1428 }
1429 if( !silent ) {
1430 add_msg_player_or_npc( rating,
1431 _( "Your %1$s mutation turns into %2$s." ),
1432 _( "<npcname>'s %1$s mutation turns into %2$s." ),
1433 mdata.name(), replace_mdata.name() );
1434 }
1435 set_mutation( replacing2 );
1436 mutation_replaced = true;
1437 }
1438 if( !mutation_replaced ) {
1439 if( mdata.mixed_effect ) {
1440 rating = m_mixed;
1441 } else if( mdata.points > 0 ) {
1442 rating = m_bad;
1443 } else if( mdata.points < 0 ) {
1444 rating = m_good;
1445 } else {
1446 rating = m_neutral;
1447 }
1448 if( !silent ) {
1449 add_msg_player_or_npc( rating,
1450 _( "You lose your %s mutation." ),
1451 _( "<npcname> loses their %s mutation." ),
1452 mdata.name() );
1453 }
1454 }
1455
1458}
@ silent
Definition: weather_type.h:56

References _, Creature::add_msg_player_or_npc(), drench_mut_calc(), mutation_branch::get_all(), has_base_trait(), has_trait(), m_bad, m_good, m_mixed, m_neutral, string_id< mutation_branch >::NULL_ID(), string_id< T >::obj(), set_highest_cat_level(), set_mutation(), silent, and unset_mutation().

Referenced by do_purify(), player::load(), mutate(), mutate_towards(), old_mutate(), perform_install(), iuse::purify_iv(), iuse::purify_smart(), remove_child_flag(), and debug_menu::wishmutate().

◆ remove_weapon()

◆ remove_worn_items_with()

std::list< item > Character::remove_worn_items_with ( std::function< bool(item &)>  filter)

Similar to remove_items_with, but considers only worn items and not their content (item::contents is not checked).

If the filter function returns true, the item is removed.

Definition at line 2294 of file character.cpp.

2295{
2296 std::list<item> result;
2297 for( auto iter = worn.begin(); iter != worn.end(); ) {
2298 if( filter( *iter ) ) {
2299 iter->on_takeoff( *this );
2300 result.splice( result.begin(), worn, iter++ );
2301 } else {
2302 ++iter;
2303 }
2304 }
2305 return result;
2306}

References worn.

Referenced by mutation_effect(), and process_items().

◆ reset()

void Character::reset ( )
overridevirtual

Handles stat and bonus reset.

Reimplemented from Creature.

Definition at line 3645 of file character.cpp.

3646{
3648 // TODO: Move reset_stats here, remove it from Creature
3650}
virtual void reset()
Handles stat and bonus reset.
Definition: creature.cpp:121

References recalculate_enchantment_cache(), and Creature::reset().

Referenced by activate_bionic(), deactivate_bionic(), game::load(), and set_stats().

◆ reset_bonuses()

void Character::reset_bonuses ( )
overridevirtual

Resets the value of all bonus fields to 0.

Reimplemented from Creature.

Definition at line 4549 of file character.cpp.

4550{
4551 // Reset all bonuses to 0 and multipliers to 1.0
4552 str_bonus = 0;
4553 dex_bonus = 0;
4554 per_bonus = 0;
4555 int_bonus = 0;
4556
4558}
virtual void reset_bonuses()
Resets the value of all bonus fields to 0.
Definition: creature.cpp:135

References dex_bonus, int_bonus, per_bonus, Creature::reset_bonuses(), and str_bonus.

◆ reset_chargen_attributes()

void Character::reset_chargen_attributes ( )

Definition at line 6772 of file character.cpp.

6773{
6774 init_age = 25;
6775 init_height = 175;
6776}

References init_age, and init_height.

◆ reset_encumbrance()

◆ reset_remote_fuel()

void Character::reset_remote_fuel ( )

Definition at line 1489 of file bionics.cpp.

1490{
1491 if( get_bionic_fueled_with( item( fuel_type_sun_light ) ).empty() ) {
1492 remove_value( "sunlight" );
1493 }
1494 remove_value( "rem_battery" );
1495}

References fuel_type_sun_light, get_bionic_fueled_with(), and Creature::remove_value().

Referenced by iuse::cable_attach(), and deactivate_bionic().

◆ reset_stats()

void Character::reset_stats ( )
overridevirtual

Resets stats, and applies effects in an idempotent manner.

Implements Creature.

Definition at line 582 of file character_turn.cpp.

583{
584 const int current_stim = get_stim();
585
586 // Trait / mutation buffs
588 add_miss_reason( _( "Your thick scales get in the way." ), 2 );
589 }
591 add_miss_reason( _( "Your chitin gets in the way." ), 1 );
592 }
594 mod_per_bonus( 2 );
595 }
597 add_miss_reason( _( "Your insect limbs get in the way." ), 2 );
598 }
600 if( !wearing_something_on( bodypart_id( "torso" ) ) ) {
601 mod_dex_bonus( 1 );
602 } else {
603 mod_dex_bonus( -1 );
604 add_miss_reason( _( "Your clothing restricts your insect arms." ), 1 );
605 }
606 }
607 if( has_trait( trait_WEBBED ) ) {
608 add_miss_reason( _( "Your webbed hands get in the way." ), 1 );
609 }
611 add_miss_reason( _( "Your arachnid limbs get in the way." ), 4 );
612 }
614 if( !wearing_something_on( bodypart_id( "torso" ) ) ) {
615 mod_dex_bonus( 2 );
616 } else if( !exclusive_flag_coverage( "OVERSIZE" ).test( bp_torso ) ) {
617 mod_dex_bonus( -2 );
618 add_miss_reason( _( "Your clothing constricts your arachnid limbs." ), 2 );
619 }
620 }
621 const auto set_fake_effect_dur = [this]( const efftype_id & type, const time_duration & dur ) {
622 effect &eff = get_effect( type );
623 if( eff.get_duration() == dur ) {
624 return;
625 }
626
627 if( eff.is_null() && dur > 0_turns ) {
628 add_effect( type, dur, num_bp );
629 } else if( dur > 0_turns ) {
630 eff.set_duration( dur );
631 } else {
633 }
634 };
635 // Painkiller
636 set_fake_effect_dur( effect_pkill, 1_turns * get_painkiller() );
637
638 // Pain
639 if( get_perceived_pain() > 0 ) {
640 const stat_mod ppen = character_effects::get_pain_penalty( *this );
641 mod_str_bonus( -ppen.strength );
642 mod_dex_bonus( -ppen.dexterity );
644 mod_per_bonus( -ppen.perception );
645 if( ppen.dexterity > 0 ) {
646 add_miss_reason( _( "Your pain distracts you!" ), static_cast<unsigned>( ppen.dexterity ) );
647 }
648 }
649
650 // Radiation
651 set_fake_effect_dur( effect_irradiated, 1_turns * get_rad() );
652 // Morale
653 const int morale = get_morale_level();
654 set_fake_effect_dur( effect_happy, 1_turns * morale );
655 set_fake_effect_dur( effect_sad, 1_turns * -morale );
656
657 // Stimulants
658 set_fake_effect_dur( effect_stim, 1_turns * current_stim );
659 set_fake_effect_dur( effect_depressants, 1_turns * -current_stim );
660 if( has_trait( trait_STIMBOOST ) ) {
661 set_fake_effect_dur( effect_stim_overdose, 1_turns * ( current_stim - 60 ) );
662 } else {
663 set_fake_effect_dur( effect_stim_overdose, 1_turns * ( current_stim - 30 ) );
664 }
665 // Starvation
666 if( get_kcal_percent() < 0.95f ) {
667 // kcal->percentage of base str
668 static const std::vector<std::pair<float, float>> starv_thresholds = { {
669 std::make_pair( 0.0f, 0.5f ),
670 std::make_pair( 0.8f, 0.1f ),
671 std::make_pair( 0.95f, 0.0f )
672 }
673 };
674
675 const int str_penalty = std::floor( multi_lerp( starv_thresholds, get_kcal_percent() ) );
676 add_miss_reason( _( "You're weak from hunger." ),
677 static_cast<unsigned>( str_penalty / 2 ) );
678 mod_str_bonus( -str_penalty );
679 mod_dex_bonus( -( str_penalty / 2 ) );
680 mod_int_bonus( -( str_penalty / 2 ) );
681 }
682 // Thirst
683 set_fake_effect_dur( effect_thirsty, 1_turns * ( get_thirst() - thirst_levels::very_thirsty ) );
685 set_fake_effect_dur( effect_sleep_deprived, 1_turns * get_sleep_deprivation() );
686 } else if( has_effect( effect_sleep_deprived ) ) {
688 }
689
690 // Dodge-related effects
692 ( encumb( bp_leg_l ) + encumb( bp_leg_r ) ) / 20.0f - encumb( bp_torso ) / 10.0f );
693 // Whiskers don't work so well if they're covered
694 if( has_trait( trait_WHISKERS ) && !wearing_something_on( bodypart_id( "mouth" ) ) ) {
695 mod_dodge_bonus( 1.5 );
696 }
698 mod_dodge_bonus( 3 );
699 }
700 // depending on mounts size, attacks will hit the mount and use their dodge rating.
701 // if they hit the player, the player cannot dodge as effectively.
702 if( is_mounted() ) {
703 mod_dodge_bonus( -4 );
704 }
705 // Spider hair is basically a full-body set of whiskers, once you get the brain for it
707 static const std::array<bodypart_id, 5> parts{ { bodypart_id( "head" ), bodypart_id( "arm_r" ), bodypart_id( "arm_l" ), bodypart_id( "leg_r" ), bodypart_id( "leg_l" ) } };
708 for( const bodypart_id &bp : parts ) {
709 if( !wearing_something_on( bp ) ) {
710 mod_dodge_bonus( +1 );
711 }
712 }
713 // Torso handled separately, bigger bonus
714 if( !wearing_something_on( bodypart_id( "torso" ) ) ) {
715 mod_dodge_bonus( 4 );
716 }
717 }
718
719 // Apply static martial arts buffs
720 martial_arts_data->ma_static_effects( *this );
721
722 if( calendar::once_every( 1_minutes ) ) {
724 }
725
726 // Effects
727 for( const auto &maps : *effects ) {
728 for( auto i : maps.second ) {
729 const auto &it = i.second;
730 if( it.is_removed() ) {
731 continue;
732 }
733 bool reduced = resists_effect( it );
734 mod_str_bonus( it.get_mod( "STR", reduced ) );
735 mod_dex_bonus( it.get_mod( "DEX", reduced ) );
736 mod_per_bonus( it.get_mod( "PER", reduced ) );
737 mod_int_bonus( it.get_mod( "INT", reduced ) );
738 }
739 }
740
741 // Bionic buffs
743 mod_str_bonus( 20 );
744 }
745
750
751 // Trait / mutation buffs
752 mod_str_bonus( std::floor( mutation_value( "str_modifier" ) ) );
753 mod_dodge_bonus( std::floor( mutation_value( "dodge_modifier" ) ) );
754
756
757 nv_cached = false;
758
759 // Reset our stats to normal levels
760 // Any persistent buffs/debuffs will take place in effects,
761 // player::suffer(), etc.
762
763 // repopulate the stat fields
768
769 // Floor for our stats. No stat changes should occur after this!
770 if( dex_cur < 0 ) {
771 dex_cur = 0;
772 }
773 if( str_cur < 0 ) {
774 str_cur = 0;
775 }
776 if( per_cur < 0 ) {
777 per_cur = 0;
778 }
779 if( int_cur < 0 ) {
780 int_cur = 0;
781 }
782
785}
float multi_lerp(const std::vector< std::pair< float, float > > &points, float x)
From points, finds p1 and p2 such that p1.first < x < p2.first Then linearly interpolates between p1....
static const efftype_id effect_sad("sad")
static const efftype_id effect_pkill("pkill")
static const trait_id trait_ARACHNID_ARMS("ARACHNID_ARMS")
static const trait_id trait_THICK_SCALES("THICK_SCALES")
static const trait_id trait_COMPOUND_EYES("COMPOUND_EYES")
static const trait_id trait_WEBBED("WEBBED")
static const bionic_id bio_hydraulics("bio_hydraulics")
static const efftype_id effect_irradiated("irradiated")
static const trait_id trait_CHITIN3("CHITIN3")
static const trait_id trait_CHITIN2("CHITIN2")
static const trait_id trait_STIMBOOST("STIMBOOST")
static const trait_id trait_CHITIN_FUR3("CHITIN_FUR3")
static const trait_id trait_WHISKERS("WHISKERS")
static const efftype_id effect_thirsty("thirsty")
static const trait_id trait_WHISKERS_RAT("WHISKERS_RAT")
static const trait_id trait_INSECT_ARMS_OK("INSECT_ARMS_OK")
static const trait_id trait_ARACHNID_ARMS_OK("ARACHNID_ARMS_OK")
static const efftype_id effect_stim_overdose("stim_overdose")
static const efftype_id effect_stim("stim")
static const efftype_id effect_happy("happy")
static const efftype_id effect_depressants("depressants")
static const efftype_id effect_sleep_deprived("sleep_deprived")
static const trait_id trait_INSECT_ARMS("INSECT_ARMS")
virtual int get_str_bonus() const
Definition: character.cpp:4122
virtual int get_int_bonus() const
Definition: character.cpp:4134
int get_mod_stat_from_bionic(const character_stat &Stat) const
Get stat bonus from bionic.
Definition: character.cpp:2115
float mabuff_dodge_bonus() const
Returns the dodge bonus from martial arts buffs.
virtual int get_per_bonus() const
Definition: character.cpp:4130
void apply_skill_boost()
Applies skill-based boosts to stats.
Definition: character.cpp:3568
void recalc_speed_bonus()
Calculates the various speed bonuses we will get from mutations, etc.
virtual int get_dex_bonus() const
Definition: character.cpp:4126
virtual void mod_dodge_bonus(float ndodge)
Definition: creature.cpp:1820
void update_mental_focus(Character &who)
Uses calc_focus_change to update the player's current focus.

References _, Creature::add_effect(), add_miss_reason(), apply_skill_boost(), bio_hydraulics, bp_leg_l, bp_leg_r, bp_torso, dex_cur, dex_max, stat_mod::dexterity, DEXTERITY, effect_depressants, effect_happy, effect_irradiated, effect_pkill, effect_sad, effect_sleep_deprived, effect_stim, effect_stim_overdose, effect_thirsty, Creature::effects, encumb(), exclusive_flag_coverage(), get_dex_bonus(), effect::get_duration(), Creature::get_effect(), get_int_bonus(), get_kcal_percent(), get_mod_stat_from_bionic(), get_morale_level(), character_effects::get_pain_penalty(), get_painkiller(), get_per_bonus(), get_perceived_pain(), get_rad(), get_sleep_deprivation(), get_stim(), get_str_bonus(), get_thirst(), harmless, has_active_bionic(), Creature::has_effect(), has_trait(), int_cur, int_max, stat_mod::intelligence, INTELLIGENCE, is_mounted(), effect::is_null(), mabuff_dodge_bonus(), martial_arts_data, mod_dex_bonus(), Creature::mod_dodge_bonus(), mod_int_bonus(), mod_per_bonus(), mod_str_bonus(), morale, multi_lerp(), mutation_value(), num_bp, nv_cached, calendar::once_every(), per_cur, per_max, stat_mod::perception, PERCEPTION, recalc_sight_limits(), recalc_speed_bonus(), Creature::remove_effect(), Creature::resists_effect(), effect::set_duration(), str_cur, str_max, stat_mod::strength, STRENGTH, trait_ARACHNID_ARMS, trait_ARACHNID_ARMS_OK, trait_CHITIN2, trait_CHITIN3, trait_CHITIN_FUR3, trait_COMPOUND_EYES, trait_INSECT_ARMS, trait_INSECT_ARMS_OK, trait_STIMBOOST, trait_THICK_SCALES, trait_WEBBED, trait_WHISKERS, trait_WHISKERS_RAT, type, character_funcs::update_mental_focus(), very_thirsty, and wearing_something_on().

Referenced by debug_menu::character_edit_menu().

◆ rest_quality()

float Character::rest_quality ( ) const

Returns >0 if character is sitting/lying and relatively inactive.

1 represents sleep on comfortable bed, so anything above that should be rare.

Definition at line 6447 of file character.cpp.

6448{
6449 // Just a placeholder for now.
6450 // TODO: Waiting/reading/being unconscious on bed/sofa/grass
6451 return has_effect( effect_sleep ) ? 1.0f : 0.0f;
6452}

References effect_sleep, and Creature::has_effect().

Referenced by mend(), and regen().

◆ restore_scent()

void Character::restore_scent ( )

restore scent after masked_scent effect run out or is removed by water

Definition at line 8766 of file character.cpp.

8767{
8768 const std::string prev_scent = get_value( "prev_scent" );
8769 if( !prev_scent.empty() ) {
8771 set_type_of_scent( scenttype_id( prev_scent ) );
8772 remove_value( "prev_scent" );
8773 remove_value( "waterproof_scent" );
8774 add_msg_if_player( m_info, _( "You smell like yourself again." ) );
8775 }
8776}
static const efftype_id effect_masked_scent("masked_scent")
void set_type_of_scent(const scenttype_id &id)
Definition: character.cpp:8756
string_id< scent_type > scenttype_id
Definition: type_id.h:42

References _, Creature::add_msg_if_player(), effect_masked_scent, Creature::get_value(), m_info, Creature::remove_effect(), Creature::remove_value(), and set_type_of_scent().

Referenced by drench(), and process_turn().

◆ resume_backlog_activity()

void Character::resume_backlog_activity ( )

Definition at line 9266 of file character.cpp.

9267{
9268 if( !backlog.empty() && backlog.front().auto_resume ) {
9269 activity = backlog.front();
9270 backlog.pop_front();
9271 }
9272}

References activity, and backlog.

Referenced by game::cancel_activity_query(), and player_activity::do_turn().

◆ roll_all_damage()

void Character::roll_all_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds all 3 types of physical damage to instance.

Definition at line 411 of file melee.cpp.

413{
414 roll_bash_damage( crit, di, average, weap );
415 roll_cut_damage( crit, di, average, weap );
416 roll_stab_damage( crit, di, average, weap );
417}
void roll_stab_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds player's total stab damage to the damage instance.
Definition: melee.cpp:1107
void roll_bash_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds player's total bash damage to the damage instance.
Definition: melee.cpp:929
void roll_cut_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds player's total cut damage to the damage instance.
Definition: melee.cpp:1033

References roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

Referenced by item::combat_info(), item::effective_dps(), and melee_attack().

◆ roll_bash_damage()

void Character::roll_bash_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds player's total bash damage to the damage instance.

Strength increases bashing damage Strength increases bashing damage Unarmed caps bash damage with unarmed weapons Bashing caps bash damage with bashing weapons Strength boosts low cap on bashing damage

Definition at line 929 of file melee.cpp.

931{
932 float bash_dam = 0.0f;
933
934 const bool unarmed = weap.is_unarmed_weapon();
935 int skill = get_skill_level( unarmed ? skill_unarmed : skill_bashing );
936 if( has_active_bionic( bio_cqb ) ) {
937 skill = BIO_CQB_LEVEL;
938 }
939
940 const int stat = get_str();
941 /** @EFFECT_STR increases bashing damage */
942 float stat_bonus = bonus_damage( !average );
943 stat_bonus += mabuff_damage_bonus( DT_BASH );
944
945 // Drunken Master damage bonuses
947 // Remember, a single drink gives 600 levels of "drunk"
948 int mindrunk = 0;
949 int maxdrunk = 0;
950 const time_duration drunk_dur = get_effect_dur( effect_drunk );
951 if( unarmed ) {
952 mindrunk = drunk_dur / 1_hours;
953 maxdrunk = drunk_dur / 25_minutes;
954 } else {
955 mindrunk = drunk_dur / 90_minutes;
956 maxdrunk = drunk_dur / 40_minutes;
957 }
958
959 bash_dam += average ? ( mindrunk + maxdrunk ) * 0.5f : rng( mindrunk, maxdrunk );
960 }
961
962 if( unarmed ) {
963 const bool left_empty = !natural_attack_restricted_on( bodypart_id( "hand_l" ) );
964 const bool right_empty = !natural_attack_restricted_on( bodypart_id( "hand_r" ) ) &&
965 weap.is_null();
966 if( left_empty || right_empty ) {
967 float per_hand = 0.0f;
968 for( const trait_id &mut : get_mutations() ) {
969 if( mut->flags.count( "NEED_ACTIVE_TO_MELEE" ) > 0 && !has_active_mutation( mut ) ) {
970 continue;
971 }
972 float unarmed_bonus = 0.0f;
973 const int bash_bonus = mut->bash_dmg_bonus;
974 if( mut->flags.count( "UNARMED_BONUS" ) > 0 && bash_bonus > 0 ) {
975 unarmed_bonus += std::min( get_skill_level( skill_unarmed ) / 2, 4 );
976 }
977 per_hand += bash_bonus + unarmed_bonus;
978 const std::pair<int, int> rand_bash = mut->rand_bash_bonus;
979 per_hand += average ? ( rand_bash.first + rand_bash.second ) / 2.0f : rng( rand_bash.first,
980 rand_bash.second );
981 }
982 bash_dam += per_hand; // First hand
983 if( left_empty && right_empty ) {
984 // Second hand
985 bash_dam += per_hand;
986 }
987 }
988
989 }
990
991 /** @EFFECT_STR increases bashing damage */
992 float weap_dam = weap.damage_melee( DT_BASH ) + stat_bonus;
993 /** @EFFECT_UNARMED caps bash damage with unarmed weapons */
994
995 /** @EFFECT_BASHING caps bash damage with bashing weapons */
996 float bash_cap = 2 * stat + 2 * skill;
997 float bash_mul = 1.0f;
998
999 // 80%, 88%, 96%, 104%, 112%, 116%, 120%, 124%, 128%, 132%
1000 if( skill < 5 ) {
1001 bash_mul = 0.8 + 0.08 * skill;
1002 } else {
1003 bash_mul = 0.96 + 0.04 * skill;
1004 }
1005
1006 if( bash_cap < weap_dam && !weap.is_null() ) {
1007 // If damage goes over cap due to low stats/skills,
1008 // scale the post-armor damage down halfway between damage and cap
1009 bash_mul *= ( 1.0f + ( bash_cap / weap_dam ) ) / 2.0f;
1010 }
1011
1012 /** @EFFECT_STR boosts low cap on bashing damage */
1013 const float low_cap = std::min( 1.0f, stat / 20.0f );
1014 const float bash_min = low_cap * weap_dam;
1015 weap_dam = average ? ( bash_min + weap_dam ) * 0.5f : rng_float( bash_min, weap_dam );
1016
1017 bash_dam += weap_dam;
1018 bash_mul *= mabuff_damage_mult( DT_BASH );
1019
1020 float armor_mult = 1.0f;
1021 int arpen = mabuff_arpen_bonus( DT_BASH );
1022
1023 // Finally, extra critical effects
1024 if( crit ) {
1025 bash_mul *= 1.5f;
1026 // 50% armor penetration
1027 armor_mult = 0.5f;
1028 }
1029
1030 di.add_damage( DT_BASH, bash_dam, arpen, armor_mult, bash_mul );
1031}
int mabuff_arpen_bonus(damage_type type) const
Returns the arpen bonus from martial arts buffs.
float bonus_damage(bool random) const
Returns the bonus bashing damage the player deals based on their stats.
Definition: melee.cpp:919
bool natural_attack_restricted_on(const bodypart_id &bp) const
Returns true if the character is wearing something on the entered body_part, ignoring items with the ...
Definition: character.cpp:1782
int mabuff_damage_bonus(damage_type type) const
Returns the flat damage bonus to given type from martial arts buffs, applied after the multiplier.
float mabuff_damage_mult(damage_type type) const
Returns the damage multiplier to given type from martial arts buffs.
static const efftype_id effect_drunk("drunk")
static const trait_id trait_DRUNKEN("DRUNKEN")
static const skill_id skill_bashing("bashing")

References damage_instance::add_damage(), bio_cqb, BIO_CQB_LEVEL, bonus_damage(), item::damage_melee(), DT_BASH, effect_drunk, Creature::get_effect_dur(), get_mutations(), get_skill_level(), get_str(), has_active_bionic(), has_active_mutation(), Creature::has_effect(), has_trait(), item::is_null(), item::is_unarmed_weapon(), mabuff_arpen_bonus(), mabuff_damage_bonus(), mabuff_damage_mult(), natural_attack_restricted_on(), rng(), rng_float(), skill_bashing, skill_unarmed, and trait_DRUNKEN.

Referenced by roll_all_damage().

◆ roll_cut_damage()

void Character::roll_cut_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds player's total cut damage to the damage instance.

Cutting increases cutting damage multiplier

Definition at line 1033 of file melee.cpp.

1035{
1036 float cut_dam = mabuff_damage_bonus( DT_CUT ) + weap.damage_melee( DT_CUT );
1037 float cut_mul = 1.0f;
1038
1039 int cutting_skill = get_skill_level( skill_cutting );
1040
1041 if( has_active_bionic( bio_cqb ) ) {
1042 cutting_skill = BIO_CQB_LEVEL;
1043 }
1044
1045 if( weap.is_unarmed_weapon() ) {
1046 // TODO: 1-handed weapons that aren't unarmed attacks
1047 const bool left_empty = !natural_attack_restricted_on( bodypart_id( "hand_l" ) );
1048 const bool right_empty = !natural_attack_restricted_on( bodypart_id( "hand_r" ) ) &&
1049 weap.is_null();
1050 if( left_empty || right_empty ) {
1051 float per_hand = 0.0f;
1052 if( has_bionic( bionic_id( "bio_razors" ) ) ) {
1053 per_hand += 2;
1054 }
1055
1056 for( const trait_id &mut : get_mutations() ) {
1057 if( mut->flags.count( "NEED_ACTIVE_TO_MELEE" ) > 0 && !has_active_mutation( mut ) ) {
1058 continue;
1059 }
1060 float unarmed_bonus = 0.0f;
1061 const int cut_bonus = mut->cut_dmg_bonus;
1062 if( mut->flags.count( "UNARMED_BONUS" ) > 0 && cut_bonus > 0 ) {
1063 unarmed_bonus += std::min( get_skill_level( skill_unarmed ) / 2, 4 );
1064 }
1065 per_hand += cut_bonus + unarmed_bonus;
1066 const std::pair<int, int> rand_cut = mut->rand_cut_bonus;
1067 per_hand += average ? ( rand_cut.first + rand_cut.second ) / 2.0f : rng( rand_cut.first,
1068 rand_cut.second );
1069 }
1070 // TODO: add acidproof check back to slime hands (probably move it elsewhere)
1071
1072 cut_dam += per_hand; // First hand
1073 if( left_empty && right_empty ) {
1074 // Second hand
1075 cut_dam += per_hand;
1076 }
1077 }
1078 }
1079
1080 if( cut_dam <= 0.0f ) {
1081 return; // No negative damage!
1082 }
1083
1084 int arpen = 0;
1085 float armor_mult = 1.0f;
1086
1087 // 80%, 88%, 96%, 104%, 112%, 116%, 120%, 124%, 128%, 132%
1088 /** @EFFECT_CUTTING increases cutting damage multiplier */
1089 if( cutting_skill < 5 ) {
1090 cut_mul *= 0.8 + 0.08 * cutting_skill;
1091 } else {
1092 cut_mul *= 0.96 + 0.04 * cutting_skill;
1093 }
1094
1095 arpen += mabuff_arpen_bonus( DT_CUT );
1096
1097 cut_mul *= mabuff_damage_mult( DT_CUT );
1098 if( crit ) {
1099 cut_mul *= 1.25f;
1100 arpen += 5;
1101 armor_mult = 0.75f; //25% armor penetration
1102 }
1103
1104 di.add_damage( DT_CUT, cut_dam, arpen, armor_mult, cut_mul );
1105}
static const skill_id skill_cutting("cutting")

References damage_instance::add_damage(), bio_cqb, BIO_CQB_LEVEL, bionic_id, item::damage_melee(), DT_CUT, get_mutations(), get_skill_level(), has_active_bionic(), has_active_mutation(), has_bionic(), item::is_null(), item::is_unarmed_weapon(), mabuff_arpen_bonus(), mabuff_damage_bonus(), mabuff_damage_mult(), natural_attack_restricted_on(), rng(), skill_cutting, and skill_unarmed.

Referenced by roll_all_damage().

◆ roll_stab_damage()

void Character::roll_stab_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds player's total stab damage to the damage instance.

Stabbing increases stabbing damage multiplier

Definition at line 1107 of file melee.cpp.

1109{
1110 float stab_dam = mabuff_damage_bonus( DT_STAB ) + weap.damage_melee( DT_STAB );
1111
1112 int unarmed_skill = get_skill_level( skill_unarmed );
1113 int stabbing_skill = get_skill_level( skill_stabbing );
1114
1115 if( has_active_bionic( bio_cqb ) ) {
1116 stabbing_skill = BIO_CQB_LEVEL;
1117 }
1118
1119 if( weap.is_unarmed_weapon() ) {
1120 const bool left_empty = !natural_attack_restricted_on( bodypart_id( "hand_l" ) );
1121 const bool right_empty = !natural_attack_restricted_on( bodypart_id( "hand_r" ) ) &&
1122 weap.is_null();
1123 if( left_empty || right_empty ) {
1124 float per_hand = 0.0f;
1125
1126 for( const trait_id &mut : get_mutations() ) {
1127 int stab_bonus = mut->pierce_dmg_bonus;
1128 int unarmed_bonus = 0;
1129 if( mut->flags.count( "UNARMED_BONUS" ) > 0 && stab_bonus > 0 ) {
1130 unarmed_bonus = std::min( unarmed_skill / 2, 4 );
1131 }
1132
1133 per_hand += stab_bonus + unarmed_bonus;
1134 }
1135
1136 if( has_bionic( bionic_id( "bio_razors" ) ) ) {
1137 per_hand += 2;
1138 }
1139
1140 stab_dam += per_hand; // First hand
1141 if( left_empty && right_empty ) {
1142 // Second hand
1143 stab_dam += per_hand;
1144 }
1145 }
1146 }
1147
1148 if( stab_dam <= 0 ) {
1149 return; // No negative stabbing!
1150 }
1151
1152 float stab_mul = 1.0f;
1153 // 66%, 76%, 86%, 96%, 106%, 116%, 122%, 128%, 134%, 140%
1154 /** @EFFECT_STABBING increases stabbing damage multiplier */
1155 if( stabbing_skill <= 5 ) {
1156 stab_mul = 0.66 + 0.1 * stabbing_skill;
1157 } else {
1158 stab_mul = 0.86 + 0.06 * stabbing_skill;
1159 }
1160 int arpen = mabuff_arpen_bonus( DT_STAB );
1161 stab_mul *= mabuff_damage_mult( DT_STAB );
1162 float armor_mult = 1.0f;
1163
1164 if( crit ) {
1165 // Critical damage bonus for stabbing scales with skill
1166 stab_mul *= 1.0 + ( stabbing_skill / 10.0 );
1167 // Stab criticals have extra %arpen
1168 armor_mult = 0.66f;
1169 }
1170
1171 di.add_damage( DT_STAB, stab_dam, arpen, armor_mult, stab_mul );
1172}

References damage_instance::add_damage(), bio_cqb, BIO_CQB_LEVEL, bionic_id, item::damage_melee(), DT_STAB, get_mutations(), get_skill_level(), has_active_bionic(), has_bionic(), item::is_null(), item::is_unarmed_weapon(), mabuff_arpen_bonus(), mabuff_damage_bonus(), mabuff_damage_mult(), natural_attack_restricted_on(), skill_stabbing, and skill_unarmed.

Referenced by roll_all_damage().

◆ rooted()

void Character::rooted ( )

Definition at line 8844 of file character.cpp.

8846{
8847 double shoe_factor = footwear_factor();
8848 if( ( has_trait( trait_ROOTS2 ) || has_trait( trait_ROOTS3 ) ) &&
8849 get_map().has_flag( flag_PLOWABLE, pos() ) && shoe_factor != 1.0 ) {
8850 if( one_in( 96 ) ) {
8851 vitamin_mod( vitamin_id( "iron" ), 1, true );
8852 vitamin_mod( vitamin_id( "calcium" ), 1, true );
8853 }
8854 if( get_thirst() <= thirst_levels::turgid && x_in_y( 75, 425 ) ) {
8855 mod_thirst( -1 );
8856 }
8857 mod_healthy_mod( 5, 50 );
8858 }
8859}
static const std::string flag_PLOWABLE("PLOWABLE")
int vitamin_mod(const vitamin_id &vit, int qty, bool capped=true)
Add or subtract vitamins from character storage pools.
string_id< vitamin > vitamin_id
Definition: type_id.h:190

References flag_PLOWABLE(), footwear_factor(), get_map(), get_thirst(), Creature::has_flag(), has_trait(), mod_healthy_mod(), mod_thirst(), one_in(), pos(), trait_ROOTS2, trait_ROOTS3, turgid, vitamin_mod(), and x_in_y().

Referenced by player_activity::do_turn().

◆ rooted_message()

void Character::rooted_message ( ) const

Handles rooting effects.

Definition at line 8834 of file character.cpp.

8835{
8836 bool wearing_shoes = is_wearing_shoes( side::LEFT ) || is_wearing_shoes( side::RIGHT );
8837 if( ( has_trait( trait_ROOTS2 ) || has_trait( trait_ROOTS3 ) ) &&
8839 !wearing_shoes ) {
8840 add_msg( m_info, _( "You sink your roots into the soil." ) );
8841 }
8842}

References _, add_msg(), flag_PLOWABLE(), get_map(), Creature::has_flag(), has_trait(), is_wearing_shoes(), LEFT, m_info, pos(), RIGHT, trait_ROOTS2, and trait_ROOTS3.

Referenced by player_activity::start_or_resume().

◆ run_cost()

int Character::run_cost ( int  base_cost,
bool  diag = false 
) const

Returns the player's modified base movement cost.

Definition at line 10026 of file character.cpp.

10027{
10028 float movecost = static_cast<float>( base_cost );
10029 if( diag ) {
10030 movecost *= 0.7071f; // because everything here assumes 100 is base
10031 }
10032 const bool flatground = movecost < 105;
10033 map &here = get_map();
10034 // The "FLAT" tag includes soft surfaces, so not a good fit.
10035 const bool on_road = flatground && here.has_flag( "ROAD", pos() );
10036 const bool on_fungus = here.has_flag_ter_or_furn( "FUNGUS", pos() );
10037
10038 if( !is_mounted() ) {
10039 if( movecost > 100 ) {
10040 movecost *= mutation_value( "movecost_obstacle_modifier" );
10041 if( movecost < 100 ) {
10042 movecost = 100;
10043 }
10044 }
10045 if( has_trait( trait_M_IMMUNE ) && on_fungus ) {
10046 if( movecost > 75 ) {
10047 // Mycal characters are faster on their home territory, even through things like shrubs
10048 movecost = 75;
10049 }
10050 }
10051
10052 // Linearly increase move cost relative to individual leg hp.
10053 movecost += 50 * ( 1 - static_cast<float>( get_part_hp_cur( bodypart_id( "leg_l" ) ) ) /
10054 static_cast<float>( get_part_hp_max( bodypart_id( "leg_l" ) ) ) );
10055 movecost += 50 * ( 1 - static_cast<float>( get_part_hp_cur( bodypart_id( "leg_r" ) ) ) /
10056 static_cast<float>( get_part_hp_max( bodypart_id( "leg_r" ) ) ) );
10057 movecost *= mutation_value( "movecost_modifier" );
10058 if( flatground ) {
10059 movecost *= mutation_value( "movecost_flatground_modifier" );
10060 }
10062 movecost *= .9f;
10063 }
10065 movecost *= ( move_mode == CMM_RUN ? 0.75f : 0.9f );
10066 } else if( has_bionic( bio_jointservo ) ) {
10067 movecost *= 0.95f;
10068 }
10069
10070 if( worn_with_flag( "SLOWS_MOVEMENT" ) ) {
10071 movecost *= 1.1f;
10072 }
10073 if( worn_with_flag( "FIN" ) ) {
10074 movecost *= 1.5f;
10075 }
10076 if( worn_with_flag( "ROLLER_INLINE" ) ) {
10077 if( on_road ) {
10078 movecost *= 0.5f;
10079 } else {
10080 movecost *= 1.5f;
10081 }
10082 }
10083 // Quad skates might be more stable than inlines,
10084 // but that also translates into a slower speed when on good surfaces.
10085 if( worn_with_flag( "ROLLER_QUAD" ) ) {
10086 if( on_road ) {
10087 movecost *= 0.7f;
10088 } else {
10089 movecost *= 1.3f;
10090 }
10091 }
10092 // Skates with only one wheel (roller shoes) are fairly less stable
10093 // and fairly slower as well
10094 if( worn_with_flag( "ROLLER_ONE" ) ) {
10095 if( on_road ) {
10096 movecost *= 0.85f;
10097 } else {
10098 movecost *= 1.1f;
10099 }
10100 }
10101
10102 movecost +=
10103 ( ( encumb( bp_foot_l ) + encumb( bp_foot_r ) ) * 2.5 +
10104 ( encumb( bp_leg_l ) + encumb( bp_leg_r ) ) * 1.5 ) / 10;
10105
10106 // ROOTS3 does slow you down as your roots are probing around for nutrients,
10107 // whether you want them to or not. ROOTS1 is just too squiggly without shoes
10108 // to give you some stability. Plants are a bit of a slow-mover. Deal.
10109 if( has_trait( trait_ROOTS3 ) && here.has_flag( "DIGGABLE", pos() ) ) {
10110 movecost += 10 * footwear_factor();
10111 }
10112
10114 movecost /= stamina_move_cost_modifier();
10115
10116 if( movecost < 20.0 ) {
10117 movecost = 20.0;
10118 }
10119 }
10120
10121 if( diag ) {
10122 movecost *= M_SQRT2;
10123 }
10124
10125 return static_cast<int>( movecost );
10126}
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const trait_id trait_PADDED_FEET("PADDED_FEET")
static const bionic_id bio_jointservo("bio_jointservo")
#define M_SQRT2
Definition: math_defines.h:29

References bio_jointservo, bonus_from_enchantments(), bp_foot_l, bp_foot_r, bp_leg_l, bp_leg_r, CMM_RUN, encumb(), footwear_factor(), get_map(), Creature::get_part_hp_cur(), Creature::get_part_hp_max(), has_active_bionic(), has_bionic(), map::has_flag(), map::has_flag_ter_or_furn(), has_trait(), is_mounted(), M_SQRT2, enchant_vals::MOVE_COST, move_mode, mutation_value(), pos(), stamina_move_cost_modifier(), trait_M_IMMUNE, trait_PADDED_FEET, trait_ROOTS3, and worn_with_flag().

Referenced by draw_speed_tab(), npc::move_to(), speed_description(), speed_rating(), npc::speed_rating(), and game::walk_move().

◆ rust_rate()

int Character::rust_rate ( ) const

Returns the player's skill rust rate.

Intelligence reduces skill rust by 10% per level above 8

Definition at line 3393 of file character.cpp.

3394{
3395 const std::string &rate_option = get_option<std::string>( "SKILL_RUST" );
3396 if( rate_option == "off" ) {
3397 return 0;
3398 }
3399
3400 // Stat window shows stat effects on based on current stat
3401 int intel = get_int();
3402 /** @EFFECT_INT reduces skill rust by 10% per level above 8 */
3403 int ret = ( ( rate_option == "vanilla" || rate_option == "capped" ) ?
3404 100 : 100 + 10 * ( intel - 8 ) );
3405
3406 ret *= mutation_value( "skill_rust_multiplier" );
3407
3408 if( ret < 0 ) {
3409 ret = 0;
3410 }
3411
3412 return ret;
3413}

References get_int(), mutation_value(), and cata::hash64_detail::ret.

Referenced by do_skill_rust(), draw_stats_info(), and set_stats().

◆ scored_crit()

bool Character::scored_crit ( float  target_dodge,
const item weap 
) const

Returns true if the player scores a critical hit.

Definition at line 783 of file melee.cpp.

784{
785 return rng_float( 0, 1.0 ) < crit_chance( hit_roll(), target_dodge, weap );
786}
double crit_chance(float roll_hit, float target_dodge, const item &weap) const
Returns the chance to critical given a hit roll and target's dodge roll.
Definition: melee.cpp:796

References crit_chance(), hit_roll(), and rng_float().

Referenced by melee_attack().

◆ sees() [1/2]

bool Character::sees ( const Creature critter) const
overridevirtual

The functions check whether this creature can see the target.

The target may either be another creature (critter), or a specific point on the map.

The function that take another creature as input should check visibility of that creature (e.g. not digging, or otherwise invisible). They must than check whether the location of the other monster is visible.

Reimplemented from Creature.

Definition at line 10451 of file character.cpp.

10452{
10453 // This handles only the player/npc specific stuff (monsters don't have traits or bionics).
10454 const int dist = rl_dist( pos(), critter.pos() );
10455 if( dist <= 3 && has_active_mutation( trait_ANTENNAE ) ) {
10456 return true;
10457 }
10458
10459 return Creature::sees( critter );
10460}
virtual bool sees(const Creature &critter) const
The functions check whether this creature can see the target.
Definition: creature.cpp:204

References has_active_mutation(), Creature::pos(), pos(), rl_dist(), Creature::sees(), and trait_ANTENNAE.

◆ sees() [2/2]

bool Character::sees ( const tripoint t,
bool  is_player = false,
int  range_mod = 0 
) const
overridevirtual

Reimplemented from Creature.

Definition at line 10434 of file character.cpp.

10435{
10436 const int wanted_range = rl_dist( pos(), t );
10437 bool can_see = is_player() ? get_map().pl_sees( t, wanted_range ) :
10438 Creature::sees( t );
10439 // Clairvoyance is now pretty cheap, so we can check it early
10440 if( wanted_range < MAX_CLAIRVOYANCE && wanted_range < clairvoyance() ) {
10441 return true;
10442 }
10443
10444 if( can_see && wanted_range > unimpaired_range() ) {
10445 can_see = false;
10446 }
10447
10448 return can_see;
10449}
int unimpaired_range() const
Returns the player maximum vision range factoring in mutations, diseases, and other effects.
Definition: character.cpp:630
int clairvoyance() const
Returns the distance the player can see through walls.
Definition: character.cpp:689
bool pl_sees(const tripoint &t, int max_range) const
Whether the player character (g->u) can see the given square (local map coordinates).
Definition: lightmap.cpp:812

References clairvoyance(), get_map(), Creature::is_player(), map::pl_sees(), pos(), rl_dist(), Creature::sees(), and unimpaired_range().

Referenced by activate_bionic(), npc::address_needs(), npc::address_player(), grid_furn_transform_queue::apply(), npc::assess_danger(), bionics_uninstall_failure(), calculate_aim_cap(), game::catch_a_monster(), game::chat(), check_mount_is_spooked(), check_mount_will_move(), npc::complain(), npc::do_reload(), draw_critter_internal(), game::draw_line(), game::draw_look_around_cursor(), draw_throw_aim(), npc::drop_items(), explosion_handler::emp_blast(), npc::enough_time_to_reload(), npc::execute_action(), game::extended_description(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), heal_actor::finish_using(), game::fling_creature(), npc::follow_distance(), game::forced_door_closing(), fungal_effects::fungalize(), generic_multi_activity_check_requirement(), get_hostile_creatures(), get_path_avoid(), game::get_player_input(), get_visible_creatures(), game::handle_action(), npc::handle_sound(), vehicle::handle_trap(), npc::heal_player(), npc::heal_self(), talk_function::hostile(), is_visible_in_range(), mdeath::jabberwock(), game::knockback(), target_ui::list_friendlies_in_lof(), game::list_items(), game::look_around(), npc::method_of_attack(), npc::move(), npc::mug_player(), iuse::note_bionics(), target_ui::panel_target_info(), npc::pick_up_item(), pl_sees(), npc::pretend_fire(), npc::pretend_heal(), game::print_creature_info(), npc::print_info(), sounds::process_sound_markers(), npc::reach_omt_destination(), npc::regen_ai_cache(), iuse::robotcontrol(), character_funcs::search_surroundings(), npc::see_item_say_smth(), activity_handlers::spellcasting_finish(), fungal_effects::spread_fungus_one_tile(), suffer_from_schizophrenia(), game::try_get_right_click_action(), character_funcs::try_uncanny_dodge(), game::update_stair_monsters(), editmap::update_view_with_help(), countdown_actor::use(), npc::use_painkiller(), and npc::wield_better_weapon().

◆ sees_with_infrared()

bool Character::sees_with_infrared ( const Creature critter) const

Check whether the this player can see the other creature with infrared.

This implies this player can see infrared and the target is visible with infrared (is warm). And of course a line of sight exists.

Definition at line 10207 of file character.cpp.

10208{
10209 if( !vision_mode_cache[IR_VISION] || !critter.is_warm() ) {
10210 return false;
10211 }
10212
10213 map &here = get_map();
10214 if( is_player() || critter.is_player() ) {
10215 // Players should not use map::sees
10216 // Likewise, players should not be "looked at" with map::sees, not to break symmetry
10217 return here.pl_line_of_sight( critter.pos(),
10219 }
10220
10221 return here.sees( pos(), critter.pos(), sight_range( current_daylight_level( calendar::turn ) ) );
10222}
double current_daylight_level(const time_point &p)
Returns the current seasonally-adjusted maximum daylight level.
Definition: calendar.cpp:171
bool sees(const tripoint &F, const tripoint &T, int range) const
Returns whether F sees T with a view range of range.
Definition: map.cpp:6269
bool pl_line_of_sight(const tripoint &t, int max_range) const
Uses the map cache to tell if the player could see the given square.
Definition: lightmap.cpp:830

References current_daylight_level(), get_map(), IR_VISION, Creature::is_player(), Creature::is_warm(), map::pl_line_of_sight(), Creature::pos(), pos(), map::sees(), sight_range(), calendar::turn, and vision_mode_cache.

Referenced by calculate_aim_cap(), draw_critter_internal(), target_ui::panel_target_info(), pl_sees(), and game::print_all_tile_info().

◆ sees_with_specials()

bool Character::sees_with_specials ( const Creature critter) const

Definition at line 6357 of file character.cpp.

6358{
6359 // electroreceptors grants vision of robots and electric monsters through walls
6361 ( critter.in_species( ROBOT ) || critter.has_flag( MF_ELECTRIC ) ) ) {
6362 return true;
6363 }
6364
6365 if( critter.digging() && has_active_bionic( bio_ground_sonar ) ) {
6366 // Bypass the check below, the bionic sonar also bypasses the sees(point) check because
6367 // walls don't block sonar which is transmitted in the ground, not the air.
6368 // TODO: this might need checks whether the player is in the air, or otherwise not connected
6369 // to the ground. It also might need a range check.
6370 return true;
6371 }
6372
6373 return false;
6374}
static const trait_id trait_ELECTRORECEPTORS("ELECTRORECEPTORS")
static const species_id ROBOT("ROBOT")
static const bionic_id bio_ground_sonar("bio_ground_sonar")
virtual bool digging() const
Definition: creature.cpp:181
@ MF_ELECTRIC
Definition: mtype.h:95

References bio_ground_sonar, Creature::digging(), has_active_bionic(), Creature::has_flag(), has_trait(), Creature::in_species(), MF_ELECTRIC, ROBOT, and trait_ELECTRORECEPTORS.

Referenced by draw_critter_internal(), target_ui::panel_target_info(), pl_sees(), and game::print_all_tile_info().

◆ set_base_age()

void Character::set_base_age ( int  age)

Definition at line 6783 of file character.cpp.

6784{
6785 init_age = age;
6786}

References age(), and init_age.

Referenced by debug_menu::character_edit_menu(), and set_description().

◆ set_base_height()

void Character::set_base_height ( int  height)

Definition at line 6812 of file character.cpp.

6813{
6815}

References height(), and init_height.

Referenced by debug_menu::character_edit_menu(), and set_description().

◆ set_check_encumbrance()

void Character::set_check_encumbrance ( bool  new_check)
inline

Definition at line 2023 of file character.h.

2023 {
2024 check_encumbrance = new_check;
2025 }

References check_encumbrance.

◆ set_destination()

void Character::set_destination ( const std::vector< tripoint > &  route,
const player_activity new_destination_activity = player_activity() 
)

◆ set_destination_activity()

void Character::set_destination_activity ( const player_activity new_destination_activity)

Definition at line 953 of file character.cpp.

954{
955 destination_activity = new_destination_activity;
956}

References destination_activity.

Referenced by set_destination().

◆ set_dex_bonus()

void Character::set_dex_bonus ( int  ndex)
virtual

Definition at line 4183 of file character.cpp.

4184{
4185 dex_bonus = ndex;
4186 dex_cur = std::max( 0, dex_max + dex_bonus );
4187}

References dex_bonus, dex_cur, and dex_max.

◆ set_fac_id()

void Character::set_fac_id ( const std::string &  my_fac_id)

Definition at line 7749 of file character.cpp.

7750{
7751 fac_id = faction_id( my_fac_id );
7752}
faction_id fac_id
Definition: character.h:2203
string_id< faction > faction_id
Definition: clzones.h:30

References fac_id.

Referenced by npc_template::load().

◆ set_fatigue()

void Character::set_fatigue ( int  nfatigue)
virtual

Definition at line 4464 of file character.cpp.

4465{
4466 nfatigue = std::max( nfatigue, 0 );
4467 if( fatigue != nfatigue ) {
4468 fatigue = nfatigue;
4469 on_stat_change( "fatigue", fatigue );
4470 }
4471}

References fatigue, and on_stat_change().

Referenced by npc::address_needs(), debug_menu::character_edit_menu(), check_needs_extremes(), environmental_revert_effect(), basecamp::finish_return(), hardcoded_effects(), mod_fatigue(), and update_needs().

◆ set_healthy()

void Character::set_healthy ( int  nhealthy)
virtual

Setters for health values exclusive to characters.

Definition at line 4266 of file character.cpp.

4267{
4268 healthy = nhealthy;
4269}

References healthy.

Referenced by debug_menu::character_edit_menu(), and environmental_revert_effect().

◆ set_healthy_mod()

void Character::set_healthy_mod ( int  nhealthy_mod)
virtual

Definition at line 4278 of file character.cpp.

4279{
4280 healthy_mod = nhealthy_mod;
4281}

References healthy_mod.

Referenced by debug_menu::character_edit_menu(), environmental_revert_effect(), suffer_from_radiation(), update_health(), and vomit().

◆ set_highest_cat_level()

void Character::set_highest_cat_level ( )

Recalculates mutation_category_level[] values for the player.

Definition at line 7793 of file character.cpp.

7794{
7796
7797 // For each of our mutations...
7798 for( const trait_id &mut : get_mutations() ) {
7799 // ...build up a map of all prerequisite/replacement mutations along the tree, along with their distance from the current mutation
7800 std::unordered_map<trait_id, int> dependency_map;
7801 build_mut_dependency_map( mut, dependency_map, 0 );
7802
7803 // Then use the map to set the category levels
7804 for( const std::pair<const trait_id, int> &i : dependency_map ) {
7805 const mutation_branch &mdata = i.first.obj();
7806 if( !mdata.flags.count( "NON_THRESH" ) ) {
7807 for( const std::string &cat : mdata.category ) {
7808 // Decay category strength based on how far it is from the current mutation
7809 mutation_category_level[cat] += 8 / static_cast<int>( std::pow( 2, i.second ) );
7810 }
7811 }
7812 }
7813 }
7814}

References build_mut_dependency_map(), mutation_branch::category, mutation_branch::flags, get_mutations(), and mutation_category_level.

Referenced by avatar::load(), mutate_towards(), remove_mutation(), and game::start_game().

◆ set_int_bonus()

void Character::set_int_bonus ( int  nint)
virtual

Definition at line 4193 of file character.cpp.

4194{
4195 int_bonus = nint;
4196 int_cur = std::max( 0, int_max + int_bonus );
4197}

References int_bonus, int_cur, and int_max.

◆ set_max_power_level()

void Character::set_max_power_level ( const units::energy npower_max)

Definition at line 1919 of file character.cpp.

1920{
1921 max_power_level = npower_max;
1922}

References max_power_level.

Referenced by bionics_install_failure(), and player::player().

◆ set_movement_mode()

virtual void Character::set_movement_mode ( character_movemode  mode)
pure virtual

Implemented in avatar, and npc.

Referenced by dismount().

◆ set_mutation()

◆ set_npc_ai_info_cache()

void Character::set_npc_ai_info_cache ( npc_ai_info  key,
double  val 
) const

Definition at line 10634 of file character.cpp.

10635{
10636 npc_ai_info_cache[key] = val;
10637}

References npc_ai_info_cache.

Referenced by npc::check_or_reload_cbm(), npc::find_reloadable(), npc::wield_better_weapon(), and npc_ai::wielded_value().

◆ set_pain()

void Character::set_pain ( int  npain)
overridevirtual

Sets new intensity of pain an reacts to it.

Reimplemented from Creature.

Definition at line 791 of file character.cpp.

792{
793 const int prev_pain = get_perceived_pain();
794 Creature::set_pain( npain );
795 const int cur_pain = get_perceived_pain();
796
797 if( cur_pain != prev_pain ) {
798 react_to_felt_pain( cur_pain - prev_pain );
799 on_stat_change( "perceived_pain", cur_pain );
800 }
801}
void react_to_felt_pain(int intensity)
Definition: character.cpp:740
virtual void set_pain(int npain)
Definition: creature.cpp:1397

References get_perceived_pain(), on_stat_change(), react_to_felt_pain(), and Creature::set_pain().

Referenced by environmental_revert_effect(), game::is_game_over(), and suffer_from_other_mutations().

◆ set_painkiller()

void Character::set_painkiller ( int  npkill)

Sets intensity of painkillers

Definition at line 9793 of file character.cpp.

9794{
9795 npkill = std::max( npkill, 0 );
9796 if( pkill != npkill ) {
9797 const int prev_pain = get_perceived_pain();
9798 pkill = npkill;
9799 on_stat_change( "pkill", pkill );
9800 const int cur_pain = get_perceived_pain();
9801
9802 if( cur_pain != prev_pain ) {
9803 react_to_felt_pain( cur_pain - prev_pain );
9804 on_stat_change( "perceived_pain", cur_pain );
9805 }
9806 }
9807}

References get_perceived_pain(), on_stat_change(), pkill, and react_to_felt_pain().

Referenced by activate_bionic(), environmental_revert_effect(), mod_painkiller(), iuse::smoking(), and iuse::weed_cake().

◆ set_per_bonus()

void Character::set_per_bonus ( int  nper)
virtual

Definition at line 4188 of file character.cpp.

4189{
4190 per_bonus = nper;
4191 per_cur = std::max( 0, per_max + per_bonus );
4192}

References per_bonus, per_cur, and per_max.

◆ set_power_level()

void Character::set_power_level ( const units::energy npower)

Definition at line 1914 of file character.cpp.

1915{
1916 power_level = std::min( npower, max_power_level );
1917}

References max_power_level, and power_level.

Referenced by activate_bionic(), avatar::create(), mod_power_level(), and player::player().

◆ set_primary_weapon()

void Character::set_primary_weapon ( const item new_weapon)

Use this when primary weapon might not exist yet.

Definition at line 171 of file melee.cpp.

172{
173 auto &body = get_body();
174 auto iter = body.find( body_part_arm_r );
175 if( iter != body.end() ) {
177 if( part.wielding.wielded == nullptr ) {
178 part.wielding.wielded = std::make_shared<item>( new_weapon );
179 } else {
180 *part.wielding.wielded = new_weapon;
181 }
182 }
183}

References Creature::body, body_part_arm_r, Creature::get_body(), Creature::get_part(), wield_status::wielded, and bodypart::wielding.

Referenced by activate_bionic(), debug_menu::character_edit_menu(), avatar::create(), deactivate_bionic(), mattack::frag(), i_rem(), load(), character_funcs::normalize(), npc::randomize(), remove_weapon(), mattack::rifle(), gun_actor::shoot(), spell_effect::spawn_ethereal_item(), npc::starting_weapon(), mattack::tankgun(), character_funcs::try_wield_contents(), npc::wield(), and avatar::wield().

◆ set_rad()

void Character::set_rad ( int  new_rad)

◆ set_skill_level()

◆ set_sleep_deprivation()

void Character::set_sleep_deprivation ( int  nsleep_deprivation)
virtual

Definition at line 4473 of file character.cpp.

4474{
4475 sleep_deprivation = std::min( static_cast< int >( sleep_deprivation_levels::massive ), std::max( 0,
4476 nsleep_deprivation ) );
4477}

References massive, and sleep_deprivation.

Referenced by debug_menu::character_edit_menu(), environmental_revert_effect(), basecamp::finish_return(), mod_sleep_deprivation(), and update_needs().

◆ set_stamina()

◆ set_stashed_activity()

void Character::set_stashed_activity ( const player_activity act,
const player_activity act_back = player_activity() 
)

Definition at line 913 of file character.cpp.

914{
916 stashed_outbounds_backlog = act_back;
917}

References act, stashed_outbounds_activity, and stashed_outbounds_backlog.

◆ set_stim()

void Character::set_stim ( int  new_stim)

Definition at line 7058 of file character.cpp.

7059{
7060 stim = new_stim;
7061}

References stim.

Referenced by activate_bionic(), environmental_revert_effect(), modify_stimulation(), and update_needs().

◆ set_stored_kcal()

void Character::set_stored_kcal ( int  kcal)
virtual

Setters for need values exclusive to characters.

Definition at line 4334 of file character.cpp.

4335{
4336 if( stored_calories != kcal ) {
4337 stored_calories = std::min( kcal, max_stored_kcal() );
4338 }
4339}

References max_stored_kcal(), and stored_calories.

Referenced by debug_menu::character_edit_menu(), npc::consume_food(), avatar::create(), environmental_revert_effect(), marloss_common(), mod_stored_kcal(), and update_stomach().

◆ set_str_bonus()

void Character::set_str_bonus ( int  nstr)
virtual

Setters for stats exclusive to characters.

Definition at line 4178 of file character.cpp.

4179{
4180 str_bonus = nstr;
4181 str_cur = std::max( 0, str_max + str_bonus );
4182}

References str_bonus, str_cur, and str_max.

◆ set_thirst()

void Character::set_thirst ( int  nthirst)
virtual

Definition at line 4446 of file character.cpp.

4447{
4448 if( thirst != nthirst ) {
4449 thirst = nthirst;
4450 on_stat_change( "thirst", thirst );
4451 }
4452}

References on_stat_change(), and thirst.

Referenced by debug_menu::character_edit_menu(), npc::consume_food(), npc::consume_food_from_camp(), environmental_revert_effect(), basecamp::finish_return(), mod_thirst(), update_stomach(), and vomit().

◆ set_time_died()

void Character::set_time_died ( const time_point time)
inline

set the turn the turn the character died if not already done

Definition at line 1479 of file character.h.

1479 {
1481 time_died = time;
1482 }
1483 }
@ time
Recharges slowly with time.

References calendar::before_time_starts, time, and time_died.

Referenced by die().

◆ set_type_of_scent()

void Character::set_type_of_scent ( const scenttype_id id)

Definition at line 8756 of file character.cpp.

8757{
8758 type_of_scent = id;
8759}

References id, and type_of_scent.

Referenced by restore_scent(), update_type_of_scent(), and change_scent_iuse::use().

◆ set_underwater()

void Character::set_underwater ( bool  x)
overridevirtual

Reimplemented from Creature.

Definition at line 10621 of file character.cpp.

10622{
10623 if( is_underwater() != x ) {
10626 }
10627}
virtual void set_underwater(bool x)
Definition: creature.cpp:176

References Creature::is_underwater(), recalc_sight_limits(), and Creature::set_underwater().

Referenced by avatar_action::swim(), game::vertical_move(), and game::walk_move().

◆ setID()

void Character::setID ( character_id  i,
bool  force = false 
)

Definition at line 483 of file character.cpp.

484{
485 if( id.is_valid() && !force ) {
486 debugmsg( "tried to set id of a npc/player, but has already a id: %d", id.get_value() );
487 } else if( !i.is_valid() && !force ) {
488 debugmsg( "tried to set invalid id of a npc/player: %d", i.get_value() );
489 } else {
490 id = i;
491 }
492}
bool is_valid() const
Definition: character_id.h:19
int get_value() const
Definition: character_id.h:23

References debugmsg, character_id::get_value(), Creature::get_value(), and character_id::is_valid().

Referenced by player::load(), game::load(), npc::randomize(), game::start_game(), and main_menu::world_tab().

◆ setpos()

◆ setx()

void Character::setx ( int  x)
inline

◆ sety()

void Character::sety ( int  y)
inline

◆ setz()

void Character::setz ( int  z)
inline

Definition at line 812 of file character.h.

812 {
813 setpos( tripoint( position.xy(), z ) );
814 }

References position, setpos(), and tripoint::xy().

Referenced by start_location::place_player(), and game::vertical_shift().

◆ shift_destination()

void Character::shift_destination ( point  shift)

Definition at line 10360 of file character.cpp.

10361{
10363 *next_expected_position += shift;
10364 }
10365
10366 for( auto &elem : auto_move_route ) {
10367 elem += shift;
10368 }
10369}

References auto_move_route, and next_expected_position.

Referenced by game::update_map().

◆ shoe_type_count()

int Character::shoe_type_count ( const itype_id it) const

Returns 1 if the player is wearing an item of that count on one foot, 2 if on both, and zero if on neither.

Definition at line 8949 of file character.cpp.

8950{
8951 int ret = 0;
8952 if( is_wearing_on_bp( it, bodypart_id( "foot_l" ) ) ) {
8953 ret++;
8954 }
8955 if( is_wearing_on_bp( it, bodypart_id( "foot_r" ) ) ) {
8956 ret++;
8957 }
8958 return ret;
8959}
bool is_wearing_on_bp(const itype_id &it, const bodypart_id &bp) const
Returns true if the player is wearing the item on the given body part.
Definition: character.cpp:3254

References is_wearing_on_bp(), and cata::hash64_detail::ret.

Referenced by avatar_action::swim(), and game::vertical_move().

◆ short_description()

std::string Character::short_description ( ) const

Definition at line 10349 of file character.cpp.

10350{
10351 return join( short_description_parts(), "; " );
10352}
std::vector< std::string > short_description_parts() const
arg_join< It, Sentinel, char > join(It begin, Sentinel end, string_view sep)
Returns an object that formats the iterator range [begin, end) with elements separated by sep.

References join(), and short_description_parts().

◆ short_description_parts()

std::vector< std::string > Character::short_description_parts ( ) const

Definition at line 10325 of file character.cpp.

10326{
10327 std::vector<std::string> result;
10328
10329 std::string gender = male ? _( "Male" ) : _( "Female" );
10330 result.push_back( name + ", " + gender );
10331 if( is_armed() ) {
10332 result.push_back( _( "Wielding: " ) + primary_weapon().tname() );
10333 }
10334 const std::string worn_str = enumerate_as_string( worn.begin(), worn.end(),
10335 []( const item & it ) {
10336 return it.tname();
10337 } );
10338 if( !worn_str.empty() ) {
10339 result.push_back( _( "Wearing: " ) + worn_str );
10340 }
10341 const int visibility_cap = 0; // no cap
10342 const auto trait_str = visible_mutations( visibility_cap );
10343 if( !trait_str.empty() ) {
10344 result.push_back( _( "Traits: " ) + trait_str );
10345 }
10346 return result;
10347}
std::string visible_mutations(int visibility_cap) const
Returns an enumeration of visible mutations with colors.
Definition: mutation.cpp:1728

References _, enumerate_as_string(), is_armed(), male, name, primary_weapon(), visible_mutations(), and worn.

Referenced by short_description().

◆ shout()

void Character::shout ( std::string  msg = "",
bool  order = false 
)

Definition at line 7632 of file character.cpp.

7633{
7634 int base = 10;
7635 std::string shout;
7636
7637 // You can't shout without your face
7638 if( has_trait( trait_PROF_FOODP ) && !( is_wearing( itype_id( "foodperson_mask" ) ) ||
7639 is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) {
7640 add_msg_if_player( m_warning, _( "You try to shout but you have no face!" ) );
7641 return;
7642 }
7643
7644 // Mutations make shouting louder, they also define the default message
7645 if( has_trait( trait_SHOUT3 ) ) {
7646 base = 20;
7647 if( msg.empty() ) {
7648 msg = is_player() ? _( "yourself let out a piercing howl!" ) : _( "a piercing howl!" );
7649 shout = "howl";
7650 }
7651 } else if( has_trait( trait_SHOUT2 ) ) {
7652 base = 15;
7653 if( msg.empty() ) {
7654 msg = is_player() ? _( "yourself scream loudly!" ) : _( "a loud scream!" );
7655 shout = "scream";
7656 }
7657 }
7658
7659 if( msg.empty() ) {
7660 msg = is_player() ? _( "yourself shout loudly!" ) : _( "a loud shout!" );
7661 shout = "default";
7662 }
7663 int noise = get_shout_volume();
7664
7665 // Minimum noise volume possible after all reductions.
7666 // Volume 1 can't be heard even by player
7667 constexpr int minimum_noise = 2;
7668
7669 if( noise <= base ) {
7670 std::string dampened_shout;
7671 std::transform( msg.begin(), msg.end(), std::back_inserter( dampened_shout ), tolower );
7672 msg = std::move( dampened_shout );
7673 }
7674
7675 // Screaming underwater is not good for oxygen and harder to do overall
7676 if( is_underwater() ) {
7678 mod_stat( "oxygen", -noise );
7679 }
7680 }
7681
7682 const int penalty = encumb( bp_mouth ) * 3 / 2;
7683 // TODO: indistinct noise descriptions should be handled in the sounds code
7684 if( noise <= minimum_noise ) {
7686 _( "The sound of your voice is almost completely muffled!" ) );
7687 msg = is_player() ? _( "your muffled shout" ) : _( "an indistinct voice" );
7688 } else if( noise * 2 <= noise + penalty ) {
7689 // The shout's volume is 1/2 or lower of what it would be without the penalty
7690 add_msg_if_player( m_warning, _( "The sound of your voice is significantly muffled!" ) );
7691 }
7692
7694 "shout", shout );
7695}
static const trait_id trait_GILLS_CEPH("GILLS_CEPH")
static const trait_id trait_GILLS("GILLS")
void shout(std::string msg="", bool order=false)
Definition: character.cpp:7632
int get_shout_volume() const
Definition: character.cpp:7589
bool move(avatar &you, map &m, const tripoint &d)
void transform(player &p, const tripoint &pos)
Transform the examined object into the object specified by its transforms_into property.
Definition: iexamine.cpp:1642

References _, Creature::add_msg_if_player(), sounds::alert, bp_mouth, encumb(), get_shout_volume(), has_trait(), Creature::is_player(), Creature::is_underwater(), is_wearing(), itype_id, m_warning, mod_stat(), avatar_action::move(), noise, sounds::order, pos(), shout(), sounds::sound(), trait_GILLS, trait_GILLS_CEPH, trait_PROF_FOODP, trait_SHOUT2, trait_SHOUT3, and iexamine::transform().

Referenced by game::chat(), dialogue::dynamic_line(), shout(), suffer_from_schizophrenia(), and suffer_while_awake().

◆ sight_impaired()

◆ sight_range()

int Character::sight_range ( int  light_level) const
overridevirtual

Returns the player's sight range.

Implements Creature.

Definition at line 606 of file character.cpp.

607{
608 if( light_level == 0 ) {
609 return 1;
610 }
611 /* Via Beer-Lambert we have:
612 * light_level * (1 / exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance) ) <= LIGHT_AMBIENT_LOW
613 * Solving for distance:
614 * 1 / exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance ) <= LIGHT_AMBIENT_LOW / light_level
615 * 1 <= exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance ) * LIGHT_AMBIENT_LOW / light_level
616 * light_level <= exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance ) * LIGHT_AMBIENT_LOW
617 * log(light_level) <= LIGHT_TRANSPARENCY_OPEN_AIR * distance + log(LIGHT_AMBIENT_LOW)
618 * log(light_level) - log(LIGHT_AMBIENT_LOW) <= LIGHT_TRANSPARENCY_OPEN_AIR * distance
619 * log(LIGHT_AMBIENT_LOW / light_level) <= LIGHT_TRANSPARENCY_OPEN_AIR * distance
620 * log(LIGHT_AMBIENT_LOW / light_level) * (1 / LIGHT_TRANSPARENCY_OPEN_AIR) <= distance
621 */
622 int range = static_cast<int>( -std::log( get_vision_threshold( static_cast<int>
623 ( get_map().ambient_light_at( pos() ) ) ) / static_cast<float>( light_level ) ) *
624 ( 1.0 / LIGHT_TRANSPARENCY_OPEN_AIR ) );
625
626 // Clamp to [1, sight_max].
627 return clamp( range, 1, sight_max );
628}
float get_vision_threshold(float light_level) const
Returns the apparent light level at which the player can see.
Definition: character.cpp:1735
static constexpr float LIGHT_TRANSPARENCY_OPEN_AIR
Definition: lightmap.h:36

References clamp(), get_map(), get_vision_threshold(), LIGHT_TRANSPARENCY_OPEN_AIR, pos(), range, and sight_max.

Referenced by game::calc_driving_offset(), overmap_sight_range(), sees_with_infrared(), and editmap::update_view_with_help().

◆ skin_name()

std::string Character::skin_name ( ) const
overridevirtual

Returns the name of the player's outer layer, e.g.

"armor plates"

Implements Creature.

Definition at line 595 of file character.cpp.

596{
597 // TODO: Return actual deflecting layer name
598 return _( "armor" );
599}

References _.

◆ sound_hallu()

void Character::sound_hallu ( )

Creates an auditory hallucination.

Definition at line 1775 of file suffer.cpp.

1776{
1777 // Random 'dangerous' sound from a random direction
1778 // 1/5 chance to be a loud sound
1779 std::vector<std::string> dir{ "north",
1780 "northeast",
1781 "northwest",
1782 "south",
1783 "southeast",
1784 "southwest",
1785 "east",
1786 "west" };
1787
1788 std::vector<std::string> dirz{ "and above you ", "and below you " };
1789
1790 std::vector<std::tuple<std::string, std::string, std::string>> desc{
1791 std::make_tuple( "whump!", "smash_fail", "t_door_c" ),
1792 std::make_tuple( "crash!", "smash_success", "t_door_c" ),
1793 std::make_tuple( "glass breaking!", "smash_success", "t_window_domestic" ) };
1794
1795 std::vector<std::tuple<std::string, std::string, std::string>> desc_big{
1796 std::make_tuple( "huge explosion!", "explosion", "default" ),
1797 std::make_tuple( "bang!", "fire_gun", "glock_19" ),
1798 std::make_tuple( "blam!", "fire_gun", "mossberg_500" ),
1799 std::make_tuple( "crash!", "smash_success", "t_wall" ),
1800 std::make_tuple( "SMASH!", "smash_success", "t_wall" ) };
1801
1802 std::string i_dir = dir[rng( 0, dir.size() - 1 )];
1803
1804 if( one_in( 10 ) ) {
1805 i_dir += " " + dirz[rng( 0, dirz.size() - 1 )];
1806 }
1807
1808 std::string i_desc;
1809 std::pair<std::string, std::string> i_sound;
1810 if( one_in( 5 ) ) {
1811 int r_int = rng( 0, desc_big.size() - 1 );
1812 i_desc = std::get<0>( desc_big[r_int] );
1813 i_sound = std::make_pair( std::get<1>( desc_big[r_int] ), std::get<2>( desc_big[r_int] ) );
1814 } else {
1815 int r_int = rng( 0, desc.size() - 1 );
1816 i_desc = std::get<0>( desc[r_int] );
1817 i_sound = std::make_pair( std::get<1>( desc[r_int] ), std::get<2>( desc[r_int] ) );
1818 }
1819
1820 add_msg( m_warning, _( "From the %1$s you hear %2$s" ), i_dir, i_desc );
1821 sfx::play_variant_sound( i_sound.first, i_sound.second, rng( 20, 80 ) );
1822}
void play_variant_sound(const std::string &id, const std::string &variant, int volume, units::angle angle, double pitch_min=-1.0, double pitch_max=-1.0)
Definition: sounds.cpp:1597

References _, add_msg(), m_warning, one_in(), sfx::play_variant_sound(), and rng().

Referenced by hardcoded_effects(), and suffer_from_schizophrenia().

◆ speed_rating()

float Character::speed_rating ( ) const
overridevirtual

Returns an approximate number of tiles this creature can travel per turn.

Implements Creature.

Reimplemented in npc.

Definition at line 10001 of file character.cpp.

10002{
10003 float ret = get_speed() / 100.0f;
10004 ret *= 100.0f / run_cost( 100, false );
10005 // Adjustment for player being able to run, but not doing so at the moment
10006 if( move_mode != CMM_RUN ) {
10007 ret *= 1.0f + ( static_cast<float>( get_stamina() ) / static_cast<float>( get_stamina_max() ) );
10008 }
10009 return ret;
10010}
int run_cost(int base_cost, bool diag=false) const
Returns the player's modified base movement cost.

References CMM_RUN, get_speed(), get_stamina(), get_stamina_max(), move_mode, cata::hash64_detail::ret, and run_cost().

◆ spores()

void Character::spores ( )

Definition at line 8778 of file character.cpp.

8779{
8780 map &here = get_map();
8781 fungal_effects fe( *g, here );
8782 //~spore-release sound
8783 sounds::sound( pos(), 10, sounds::sound_t::combat, _( "Pouf!" ), false, "misc", "puff" );
8784 for( const tripoint &sporep : here.points_in_radius( pos(), 1 ) ) {
8785 if( sporep == pos() ) {
8786 continue;
8787 }
8788 fe.fungalize( sporep, this, 0.25 );
8789 }
8790}

References _, sounds::combat, fungal_effects::fungalize(), g, get_map(), map::points_in_radius(), pos(), and sounds::sound().

Referenced by activate_mutation(), hardcoded_effects(), and suffer_while_awake().

◆ stability_roll()

float Character::stability_roll ( ) const
overridevirtual

Returns value of player's stable footing.

Strength improves player stability roll Perception slightly improves player stability roll Dexterity slightly improves player stability roll Melee improves player stability roll

Implements Creature.

Definition at line 10644 of file character.cpp.

10645{
10646 /** @EFFECT_STR improves player stability roll */
10647
10648 /** @EFFECT_PER slightly improves player stability roll */
10649
10650 /** @EFFECT_DEX slightly improves player stability roll */
10651
10652 /** @EFFECT_MELEE improves player stability roll */
10653 return get_melee() + get_str() + ( get_per() / 3.0f ) + ( get_dex() / 4.0f );
10654}
float get_melee() const override
Returns melee skill level, to be used to throttle dodge practice.
Definition: melee.cpp:914

References get_dex(), get_melee(), get_per(), and get_str().

Referenced by on_hit().

◆ stamina_move_cost_modifier()

float Character::stamina_move_cost_modifier ( ) const

Definition at line 7151 of file character.cpp.

7152{
7153 // Both walk and run speed drop to half their maximums as stamina approaches 0.
7154 // Convert stamina to a float first to allow for decimal place carrying
7155 float stamina_modifier = ( static_cast<float>( get_stamina() ) / get_stamina_max() + 1 ) / 2;
7156 if( move_mode == CMM_RUN && get_stamina() >= 0 ) {
7157 // Rationale: Average running speed is 2x walking speed. (NOT sprinting)
7158 stamina_modifier *= 2.0;
7159 }
7160 if( move_mode == CMM_CROUCH ) {
7161 stamina_modifier *= 0.5;
7162 }
7163 return stamina_modifier;
7164}

References CMM_CROUCH, CMM_RUN, get_stamina(), get_stamina_max(), and move_mode.

Referenced by burn_move_stamina(), and run_cost().

◆ start_destination_activity()

void Character::start_destination_activity ( )

Definition at line 10523 of file character.cpp.

10524{
10525 if( !has_destination_activity() ) {
10526 debugmsg( "Tried to start invalid destination activity" );
10527 return;
10528 }
10529
10532}
void clear_destination()
bool has_destination_activity() const

References assign_activity(), clear_destination(), debugmsg, get_destination_activity(), and has_destination_activity().

Referenced by game::handle_action(), and npc::move().

◆ start_hauling()

void Character::start_hauling ( )

Definition at line 9168 of file character.cpp.

9169{
9170 add_msg( _( "You start hauling items along the ground." ) );
9171 if( is_armed() ) {
9172 add_msg( m_warning, _( "Your hands are not free, which makes hauling slower." ) );
9173 }
9174 hauling = true;
9175}

References _, add_msg(), hauling, is_armed(), and m_warning.

Referenced by haul().

◆ stop_hauling()

void Character::stop_hauling ( )

Definition at line 9177 of file character.cpp.

9178{
9179 add_msg( _( "You stop hauling items." ) );
9180 hauling = false;
9181 if( has_activity( ACT_MOVE_ITEMS ) ) {
9183 }
9184}

References _, ACT_MOVE_ITEMS, add_msg(), cancel_activity(), has_activity(), and hauling.

Referenced by cancel_activity(), haul(), game::place_player(), avatar::set_movement_mode(), and game::vertical_move().

◆ store()

void Character::store ( JsonOut json) const
protected

Load variables from json into object.

These variables are common to both the avatar and NPCs.

Definition at line 653 of file savegame_json.cpp.

654{
655 Creature::store( json );
656
657 // assumes already in Character object
658 // positional data
659 json.member( "posx", position.x );
660 json.member( "posy", position.y );
661 json.member( "posz", position.z );
662
663 // stat
664 json.member( "str_cur", str_cur );
665 json.member( "str_max", str_max );
666 json.member( "dex_cur", dex_cur );
667 json.member( "dex_max", dex_max );
668 json.member( "int_cur", int_cur );
669 json.member( "int_max", int_max );
670 json.member( "per_cur", per_cur );
671 json.member( "per_max", per_max );
672
673 json.member( "str_bonus", str_bonus );
674 json.member( "dex_bonus", dex_bonus );
675 json.member( "per_bonus", per_bonus );
676 json.member( "int_bonus", int_bonus );
677
678 json.member( "name", name );
679
680 json.member( "base_age", init_age );
681 json.member( "base_height", init_height );
682
683 if( prof.is_valid() ) {
684 json.member( "profession", prof );
685 }
686 json.member( "custom_profession", custom_profession );
687
688 // health
689 json.member( "healthy", healthy );
690 json.member( "healthy_mod", healthy_mod );
691 json.member( "healed_24h", healed_total );
692
693 // status
694 json.member( "temp_cur", temp_cur );
695 json.member( "temp_conv", temp_conv );
696 json.member( "frostbite_timer", frostbite_timer );
697 json.member( "body_wetness", body_wetness );
698
699 // needs
700 json.member( "thirst", thirst );
701 json.member( "fatigue", fatigue );
702 json.member( "sleep_deprivation", sleep_deprivation );
703 json.member( "stored_calories", stored_calories );
704 json.member( "radiation", radiation );
705 json.member( "stamina", stamina );
706 json.member( "vitamin_levels", vitamin_levels );
707 json.member( "pkill", pkill );
708 json.member( "omt_path", omt_path );
709 json.member( "consumption_history", consumption_history );
710
711 // crafting etc
712 json.member( "destination_activity", destination_activity );
713 json.member( "activity", activity );
714 json.member( "stashed_outbounds_activity", stashed_outbounds_activity );
715 json.member( "stashed_outbounds_backlog", stashed_outbounds_backlog );
716 json.member( "backlog", backlog );
717 json.member( "activity_vehicle_part_index", activity_vehicle_part_index ); // NPC activity
718
719 // handling for storing activity requirements
720 if( !backlog.empty() && !backlog.front().str_values.empty() && ( ( activity &&
721 activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) || ( destination_activity &&
722 destination_activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) ) ) {
723 requirement_data things_to_fetch = requirement_id( backlog.front().str_values.back() ).obj();
724 json.member( "fetch_data", things_to_fetch );
725 }
726
727 const item &weapon = primary_weapon();
728 if( !weapon.is_null() ) {
729 json.member( "weapon", weapon ); // also saves contents
730 }
731
732 json.member( "stim", stim );
733 json.member( "type_of_scent", type_of_scent );
734
735 // breathing
736 json.member( "oxygen", oxygen );
737
738 // traits: permanent 'mutations' more or less
739 json.member( "traits", my_traits );
740 json.member( "mutations", my_mutations );
741 json.member( "magic", magic );
742 json.member( "martial_arts_data", martial_arts_data );
743 // "Fracking Toasters" - Saul Tigh, toaster
744 json.member( "my_bionics", *my_bionics );
745
746 json.member_as_string( "move_mode", move_mode );
747
748 // storing the mount
749 if( is_mounted() ) {
750 json.member( "mounted_creature", g->critter_tracker->temporary_id( *mounted_creature ) );
751 }
752
753 morale->store( json );
754
755 // skills
756 json.member( "skills" );
757 json.start_object();
758 for( const auto &pair : *_skills ) {
759 json.member( pair.first.str(), pair.second );
760 }
761 json.end_object();
762
763 // npc: unimplemented, potentially useful
764 json.member( "learned_recipes", *learned_recipes );
765 autolearn_skills_stamp->clear(); // Invalidates the cache
766
767 // npc; unimplemented
768 if( power_level < 1_kJ ) {
769 json.member( "power_level", std::to_string( units::to_joule( power_level ) ) + " J" );
770 } else {
771 json.member( "power_level", units::to_kilojoule( power_level ) );
772 }
773 json.member( "max_power_level", units::to_kilojoule( max_power_level ) );
774
775 if( !overmap_time.empty() ) {
776 json.member( "overmap_time" );
777 json.start_array();
778 for( const std::pair<const point_abs_omt, time_duration> &pr : overmap_time ) {
779 json.write( pr.first );
780 json.write( pr.second );
781 }
782 json.end_array();
783 }
784 json.member( "stomach", stomach );
785 json.member( "automoveroute", auto_move_route );
786 json.member( "known_traps" );
787 json.start_array();
788 for( const auto &elem : known_traps ) {
789 json.start_object();
790 json.member( "x", elem.first.x );
791 json.member( "y", elem.first.y );
792 json.member( "z", elem.first.z );
793 json.member( "trap", elem.second );
794 json.end_object();
795 }
796 json.end_array();
797}
void store(JsonOut &jsout) const
These two functions are responsible for storing and loading the members of this class to/from json da...
void member_as_string(const std::string &name, const T &value)
Definition: json.h:746
void end_array()
Definition: json.cpp:2150
void start_array(bool wrap=false)
Definition: json.cpp:2139
void start_object(bool wrap=false)
Definition: json.cpp:2120
void write(T val)
Definition: json.h:615
void end_object()
Definition: json.cpp:2131
void member(const std::string &name)
Definition: json.cpp:2235

References _skills, activity, activity_vehicle_part_index, auto_move_route, autolearn_skills_stamp, backlog, body_wetness, consumption_history, custom_profession, destination_activity, dex_bonus, dex_cur, dex_max, JsonOut::end_array(), JsonOut::end_object(), fatigue, frostbite_timer, g, healed_total, healthy, healthy_mod, player_activity::id(), init_age, init_height, int_bonus, int_cur, int_max, is_mounted(), item::is_null(), string_id< T >::is_valid(), known_traps, learned_recipes, magic, martial_arts_data, max_power_level, JsonOut::member(), JsonOut::member_as_string(), morale, mounted_creature, move_mode, my_bionics, my_mutations, my_traits, name, string_id< T >::obj(), omt_path, overmap_time, oxygen, per_bonus, per_cur, per_max, pkill, position, power_level, primary_weapon(), prof, radiation, sleep_deprivation, stamina, JsonOut::start_array(), JsonOut::start_object(), stashed_outbounds_activity, stashed_outbounds_backlog, stim, stomach, Creature::store(), stored_calories, str_bonus, str_cur, str_max, temp_conv, temp_cur, thirst, units::to_joule(), units::to_kilojoule(), to_string(), type_of_scent, vitamin_levels, JsonOut::write(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by player::store().

◆ suffer()

void Character::suffer ( )

Handles a large number of timers decrementing and other randomized effects.

Definition at line 1534 of file suffer.cpp.

1535{
1536 const int current_stim = get_stim();
1537 // TODO: Remove this section and encapsulate hp_cur
1538 for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
1539 if( elem.second.get_hp_cur() <= 0 ) {
1540 add_effect( effect_disabled, 1_turns, elem.first->token );
1541 }
1542 }
1543
1544 for( bionic &bio : *my_bionics ) {
1545 process_bionic( bio );
1546 }
1547
1548 for( std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
1549 const mutation_branch &mdata = mut.first.obj();
1550 if( calendar::once_every( 1_minutes ) ) {
1551 suffer_water_damage( mdata );
1552 }
1553 char_trait_data &tdata = mut.second;
1554 if( tdata.powered ) {
1555 suffer_mutation_power( mdata, tdata );
1556 }
1557 }
1558
1559 if( is_underwater() ) {
1561 }
1562
1564
1565 if( !in_sleep_state() ) {
1566 suffer_while_awake( current_stim );
1567 } // Done with while-awake-only effects
1568
1569 if( has_trait( trait_ASTHMA ) ) {
1570 suffer_from_asthma( current_stim );
1571 }
1574 }
1575
1581 suffer_from_stimulants( current_stim );
1583 // Stimulants can lessen the PERCEIVED effects of sleep deprivation, but
1584 // they do nothing to cure it. As such, abuse is even more dangerous now.
1585 if( current_stim > 0 ) {
1586 // 100% of blacking out = 20160sd ; Max. stim modifier = 12500sd @ 250stim
1587 // Note: Very high stim already has its own slew of bad effects,
1588 // so the "useful" part of this bonus is actually lower.
1589 sleep_deprivation -= current_stim * 50;
1590 }
1591
1593 //Suffer from enchantments
1594 enchantment_cache->activate_passive( *this );
1595
1596 if( calendar::once_every( 1_hours ) ) {
1598 }
1599}
void suffer_in_sunlight()
Definition: suffer.cpp:809
void suffer_from_artifacts()
Definition: suffer.cpp:1383
void suffer_feral_kill_withdrawl()
Definition: suffer.cpp:729
void suffer_from_addictions()
Definition: suffer.cpp:277
void suffer_from_stimulants(int current_stim)
Definition: suffer.cpp:1405
void suffer_mutation_power(const mutation_branch &mdata, char_trait_data &tdata)
Definition: suffer.cpp:207
void suffer_water_damage(const mutation_branch &mdata)
suffer() subcalls
Definition: suffer.cpp:187
void suffer_while_awake(int current_stim)
Definition: suffer.cpp:304
void process_bionic(bionic &bio)
Handles bionic effects over time of the entered bionic.
Definition: bionics.cpp:1568
void suffer_from_other_mutations()
Definition: suffer.cpp:1036
void suffer_without_sleep(int sleep_deprivation)
Definition: suffer.cpp:1447
void suffer_while_underwater()
Definition: suffer.cpp:254
void suffer_from_bad_bionics()
Definition: suffer.cpp:1289
void suffer_from_radiation()
Definition: suffer.cpp:1145
void suffer_from_asthma(int current_stim)
Definition: suffer.cpp:621
static const trait_id trait_PROF_FERAL("PROF_FERAL")
static const efftype_id effect_accumulated_mutagen("accumulated_mutagen")
static const efftype_id effect_feral_killed_recently("feral_killed_recently")
static const efftype_id effect_disabled("disabled")
static const trait_id trait_ASTHMA("ASTHMA")

References Creature::add_effect(), effect_accumulated_mutagen, effect_disabled, effect_feral_killed_recently, enchantment_cache, Creature::get_body(), get_sleep_deprivation(), get_stim(), Creature::has_effect(), has_trait(), in_sleep_state(), Creature::is_underwater(), my_bionics, my_mutations, num_bp, calendar::once_every(), char_trait_data::powered, process_bionic(), sleep_deprivation, suffer_feral_kill_withdrawl(), suffer_from_addictions(), suffer_from_artifacts(), suffer_from_asthma(), suffer_from_bad_bionics(), suffer_from_other_mutations(), suffer_from_radiation(), suffer_from_stimulants(), suffer_in_sunlight(), suffer_mutation_power(), suffer_water_damage(), suffer_while_awake(), suffer_while_underwater(), suffer_without_sleep(), trait_ASTHMA, and trait_PROF_FERAL.

Referenced by process_turn().

◆ suffer_feral_kill_withdrawl()

void Character::suffer_feral_kill_withdrawl ( )
private

Definition at line 729 of file suffer.cpp.

730{
731 // If we somehow triggered this while content with our bloodshed, cancel.
733 return;
734 }
735 // Once every 4 hours
736 if( calendar::once_every( 4_hours ) ) {
737 // Select a random side effect:
738 switch( dice( 1, 4 ) ) {
739 default:
740 case 1:
741 // Feel ill, overcome with nausea if awake. Additional chance of unexplained bleeding.
742 mod_healthy_mod( -50, -500 );
743 if( !in_sleep_state() ) {
744 add_msg_if_player( m_bad, _( "You feel as if your insides are rotting away." ) );
745 vomit();
746 if( one_in( 3 ) ) {
747 add_msg_if_player( m_bad, _( "Blood starts leaking from your eyes and nose." ) );
748 add_effect( effect_bleed, 10_minutes, bp_head );
749 add_effect( effect_blind, rng( 1_seconds, 30_seconds ) );
750 }
751 } else {
752 add_msg_if_player( m_bad, _( "You feel a bit queasy in your sleep." ) );
753 if( one_in( 3 ) ) {
754 add_msg_if_player( m_bad, _( "You wake up bloody for some reason." ) );
755 wake_up();
756 add_effect( effect_bleed, 10_minutes, bp_head );
757 add_effect( effect_blind, rng( 1_seconds, 30_seconds ) );
758 }
759 }
760 break;
761 case 2:
762 // Empty stamina and inflict fatigue, pain if awake.
763 mod_fatigue( rng( 5, 10 ) );
764 set_stamina( get_stamina() * 1 / ( rng( 3, 8 ) ) );
765 if( !in_sleep_state() ) {
766 add_msg_if_player( m_bad, _( "Your head aches as a wave of exhaustion passes through you." ) );
767 mod_pain( rng( 10, 25 ) );
768 } else {
769 add_msg_if_player( m_bad, _( "You stir restlessly in your sleep." ) );
770 }
771 break;
772 case 3:
773 // Adrenaline rush plus side effects from panic. Chance it will wake you up anyway.
774 if( !in_sleep_state() ) {
775 add_msg_if_player( m_bad, _( "A pang of terror stirs your fight-or-flight response!" ) );
776 add_effect( effect_adrenaline, rng( 3_minutes, 5_minutes ) );
777 mod_stim( rng( 5, 10 ) );
778 add_morale( MORALE_FEELING_BAD, -5, -25, 10_minutes, 3_minutes, true );
779 } else {
780 if( !one_in( 4 ) ) {
781 add_msg_if_player( m_bad, _( "You jolt awake in a panic attack!" ) );
782 wake_up();
783 add_effect( effect_adrenaline, rng( 3_minutes, 5_minutes ) );
784 mod_stim( rng( 5, 10 ) );
785 add_morale( MORALE_FEELING_BAD, -5, -25, 10_minutes, 3_minutes, true );
786 } else {
787 add_msg_if_player( m_bad, _( "You have a vivid nightmare that almost wakes you up." ) );
788 }
789 }
790 break;
791 case 4:
792 // The others are displeased with your lack of bloodshed, can sleep through the mental contact itself.
793 add_effect( effect_attention, rng( 3_hours, 6_hours ), num_bp, rng( 1, 4 ), false, true );
794 if( !in_sleep_state() ) {
796 _( "You feel like something is judging you from afar, leaving your head spinning." ) );
797 add_effect( effect_shakes, 5_minutes );
798 add_effect( effect_stunned, rng( 1_turns, 10_turns ) );
799 } else {
801 _( "You have a vivid nightmare about being deemed unworthy by a higher power." ) );
802 }
803 break;
804 }
805 }
806
807}
static const efftype_id effect_blind("blind")
static const efftype_id effect_bleed("bleed")
static const efftype_id effect_adrenaline("adrenaline")
static const efftype_id effect_attention("attention")
static const efftype_id effect_shakes("shakes")
static const efftype_id effect_stunned("stunned")

References _, Creature::add_effect(), add_morale(), Creature::add_msg_if_player(), bp_head, dice(), effect_adrenaline, effect_attention, effect_bleed, effect_blind, effect_feral_killed_recently, effect_shakes, effect_stunned, get_stamina(), Creature::has_effect(), in_sleep_state(), m_bad, mod_fatigue(), mod_healthy_mod(), mod_pain(), mod_stim(), MORALE_FEELING_BAD, num_bp, calendar::once_every(), one_in(), rng(), set_stamina(), vomit(), and wake_up().

Referenced by suffer().

◆ suffer_from_addictions()

void Character::suffer_from_addictions ( )
private

Definition at line 277 of file suffer.cpp.

278{
279 time_duration timer = -6_hours;
280 if( has_trait( trait_ADDICTIVE ) ) {
281 timer = -10_hours;
282 } else if( has_trait( trait_NONADDICTIVE ) ) {
283 timer = -3_hours;
284 }
285 for( addiction &cur_addiction : addictions ) {
286 if( cur_addiction.sated <= 0_turns &&
287 cur_addiction.intensity >= MIN_ADDICTION_LEVEL ) {
288 addict_effect( *this, cur_addiction );
289 }
290 cur_addiction.sated -= 1_turns;
291 // Higher intensity addictions heal faster
292 if( cur_addiction.sated - 10_minutes * cur_addiction.intensity < timer ) {
293 if( cur_addiction.intensity <= 2 ) {
294 rem_addiction( cur_addiction.type );
295 break;
296 } else {
297 cur_addiction.intensity--;
298 cur_addiction.sated = 0_turns;
299 }
300 }
301 }
302}
void addict_effect(Character &u, addiction &add)
Definition: addiction.cpp:57
constexpr int MIN_ADDICTION_LEVEL
Definition: addiction.h:13
void rem_addiction(add_type type)
Removes an addition from the player.
Definition: suffer.cpp:2015

References addict_effect(), addictions, has_trait(), MIN_ADDICTION_LEVEL, rem_addiction(), trait_ADDICTIVE, and trait_NONADDICTIVE.

Referenced by suffer().

◆ suffer_from_artifacts()

void Character::suffer_from_artifacts ( )
private

Definition at line 1383 of file suffer.cpp.

1384{
1385 // Artifact effects
1387 add_effect( effect_attention, 3_turns );
1388 }
1389
1391 get_weather().weather_id->precip < precip_class::heavy ) {
1395 }
1396
1397 if( has_artifact_with( AEP_MUTAGENIC ) && one_turn_in( 48_hours ) ) {
1398 mutate();
1399 }
1400 if( has_artifact_with( AEP_FORCE_TELEPORT ) && one_turn_in( 1_hours ) ) {
1401 teleport::teleport( *this );
1402 }
1403}
const weather_type_id & get_bad_weather() const
weather_type_id weather_override
Definition: weather.h:199
@ AEP_MUTAGENIC
Definition: enums.h:130
@ AEP_FORCE_TELEPORT
Definition: enums.h:138
@ AEP_ATTENTION
Definition: enums.h:131
@ AEP_BAD_WEATHER
Definition: enums.h:140
const weather_generator & get_cur_weather_gen() const
Definition: weather.cpp:1049
void set_nextweather(time_point t)
Definition: weather.cpp:1101

References Creature::add_effect(), AEP_ATTENTION, AEP_BAD_WEATHER, AEP_FORCE_TELEPORT, AEP_MUTAGENIC, effect_attention, weather_generator::get_bad_weather(), weather_manager::get_cur_weather_gen(), get_weather(), has_artifact_with(), heavy, mutate(), calendar::once_every(), one_turn_in(), weather_manager::set_nextweather(), teleport::teleport(), calendar::turn, and weather_manager::weather_override.

Referenced by suffer().

◆ suffer_from_asthma()

void Character::suffer_from_asthma ( int  current_stim)
private

Definition at line 621 of file suffer.cpp.

622{
626 return;
627 }
628 // Cap effect of stimulants on asthma attacks to 1 per minute (or risk instantly killing players that rely on oxygen tanks)
629 if( !one_in( std::max( to_turns<int>( 1_minutes ),
630 ( to_turns<int>( 6_hours ) - current_stim * 180 ) ) *
632 1 ) ) ) {
633 return;
634 }
635 bool auto_use = has_charges( itype_inhaler, 1 ) || has_charges( itype_oxygen_tank, 1 ) ||
637 bool oxygenator = has_bionic( bio_gills ) && get_power_level() >= ( bio_gills->power_trigger / 8 );
638 if( is_underwater() ) {
639 oxygen = oxygen / 2;
640 auto_use = false;
641 }
642
643 add_msg_player_or_npc( m_bad, _( "You have an asthma attack!" ),
644 "<npcname> starts wheezing and coughing." );
645
647 inventory map_inv;
648 map_inv.form_from_map( g->u.pos(), 2, &g->u );
649 // check if an inhaler is somewhere near
650 bool nearby_use = auto_use || oxygenator || map_inv.has_charges( itype_inhaler, 1 ) ||
651 map_inv.has_charges( itype_oxygen_tank, 1 ) ||
652 map_inv.has_charges( itype_smoxygen_tank, 1 );
653 // check if character has an oxygenator first
654 if( oxygenator ) {
656 add_msg_if_player( m_info, _( "You use your Oxygenator to clear it up, "
657 "then go back to sleep." ) );
658 } else if( auto_use ) {
660 add_msg_if_player( m_info, _( "You use your inhaler and go back to sleep." ) );
661 add_effect( effect_took_antiasthmatic, rng( 1_hours, 2_hours ) );
662 } else if( use_charges_if_avail( itype_oxygen_tank, 1 ) ||
664 add_msg_if_player( m_info, _( "You take a deep breath from your oxygen tank "
665 "and go back to sleep." ) );
666 }
667 } else if( nearby_use ) {
668 // create new variable to resolve a reference issue
669 int amount = 1;
670 map &here = get_map();
671 if( !here.use_charges( g->u.pos(), 2, itype_inhaler, amount ).empty() ) {
672 add_msg_if_player( m_info, _( "You use your inhaler and go back to sleep." ) );
673 add_effect( effect_took_antiasthmatic, rng( 1_hours, 2_hours ) );
674 } else if( !here.use_charges( g->u.pos(), 2, itype_oxygen_tank, amount ).empty() ||
675 !here.use_charges( g->u.pos(), 2, itype_smoxygen_tank, amount ).empty() ) {
676 add_msg_if_player( m_info, _( "You take a deep breath from your oxygen tank "
677 "and go back to sleep." ) );
678 }
679 } else {
680 add_effect( effect_asthma, rng( 5_minutes, 20_minutes ) );
681 if( has_effect( effect_sleep ) ) {
682 wake_up();
683 } else {
684 if( !is_npc() ) {
685 g->cancel_activity_or_ignore_query( distraction_type::asthma,
686 _( "You can't focus while choking!" ) );
687 }
688 }
689 }
690 } else if( auto_use ) {
691 int charges = 0;
693 moves -= 40;
694 charges = charges_of( itype_inhaler );
695 if( charges == 0 ) {
696 add_msg_if_player( m_bad, _( "You use your last inhaler charge." ) );
697 } else {
698 add_msg_if_player( m_info, vgettext( "You use your inhaler, "
699 "only %d charge left.",
700 "You use your inhaler, "
701 "only %d charges left.", charges ),
702 charges );
703 }
704 add_effect( effect_took_antiasthmatic, rng( 1_hours, 2_hours ) );
705 } else if( use_charges_if_avail( itype_oxygen_tank, 1 ) ||
707 moves -= 500; // synched with use action
709 if( charges == 0 ) {
710 add_msg_if_player( m_bad, _( "You breathe in last bit of oxygen "
711 "from the tank." ) );
712 } else {
713 add_msg_if_player( m_info, vgettext( "You take a deep breath from your oxygen "
714 "tank, only %d charge left.",
715 "You take a deep breath from your oxygen "
716 "tank, only %d charges left.", charges ),
717 charges );
718 }
719 }
720 } else {
721 add_effect( effect_asthma, rng( 5_minutes, 20_minutes ) );
722 if( !is_npc() ) {
723 g->cancel_activity_or_ignore_query( distraction_type::asthma,
724 _( "You can't focus while choking!" ) );
725 }
726 }
727}
bool use_charges_if_avail(const itype_id &it, int quantity)
Definition: character.cpp:9654
bool has_charges(const itype_id &it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >) const
Definition: inventory.cpp:893
std::list< item > use_charges(const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >, basecamp *bcp=nullptr)
Definition: map.cpp:5037
static const efftype_id effect_datura("datura")
static const efftype_id effect_narcosis("narcosis")
static const efftype_id effect_asthma("asthma")
static const itype_id itype_oxygen_tank("oxygen_tank")
static const itype_id itype_inhaler("inhaler")
static const itype_id itype_smoxygen_tank("smoxygen_tank")
static const efftype_id effect_cough_aggravated_asthma("cough_aggravated_asthma")
static const bionic_id bio_gills("bio_gills")
static const efftype_id effect_took_antiasthmatic("took_antiasthmatic")

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), asthma, bio_gills, visitable< Character >::charges_of(), effect_adrenaline, effect_asthma, effect_cough_aggravated_asthma, effect_datura, effect_narcosis, effect_sleep, effect_took_antiasthmatic, inventory::form_from_map(), g, get_map(), get_power_level(), has_bionic(), has_charges(), inventory::has_charges(), Creature::has_effect(), in_sleep_state(), Creature::is_npc(), Creature::is_underwater(), itype_inhaler, itype_oxygen_tank, itype_smoxygen_tank, m_bad, m_info, mod_power_level(), Creature::moves, one_in(), oxygen, bionic_data::power_trigger, rng(), map::use_charges(), use_charges_if_avail(), vgettext(), and wake_up().

Referenced by suffer().

◆ suffer_from_bad_bionics()

void Character::suffer_from_bad_bionics ( )
private

Definition at line 1289 of file suffer.cpp.

1290{
1291 // Negative bionics effects
1293 one_turn_in( 2_hours ) &&
1295 add_msg_if_player( m_bad, _( "You suffer a painful electrical discharge!" ) );
1296 mod_pain( 1 );
1297 moves -= 150;
1299
1300 item &weapon = primary_weapon();
1301 if( weapon.typeId() == itype_e_handcuffs && weapon.charges > 0 ) {
1302 weapon.charges -= rng( 1, 3 ) * 50;
1303 if( weapon.charges < 1 ) {
1304 weapon.charges = 1;
1305 }
1306
1307 add_msg_if_player( m_good, _( "The %s seems to be affected by the discharge." ),
1308 weapon.tname() );
1309 }
1310 sfx::play_variant_sound( "bionics", "elec_discharge", 100 );
1311 }
1312 if( has_bionic( bio_dis_acid ) && one_turn_in( 150_minutes ) ) {
1313 add_msg_if_player( m_bad, _( "You suffer a burning acidic discharge!" ) );
1314 hurtall( 1, nullptr );
1315 sfx::play_variant_sound( "bionics", "acid_discharge", 100 );
1316 sfx::do_player_death_hurt( g->u, false );
1317 }
1318 if( has_bionic( bio_drain ) && get_power_level() > 24_kJ && one_turn_in( 1_hours ) ) {
1319 add_msg_if_player( m_bad, _( "Your batteries discharge slightly." ) );
1320 mod_power_level( -25_kJ );
1321 sfx::play_variant_sound( "bionics", "elec_crackle_low", 100 );
1322 }
1323 if( has_bionic( bio_noise ) && one_turn_in( 50_minutes ) &&
1325 // TODO: NPCs with said bionic
1326 if( !is_deaf() ) {
1327 add_msg( m_bad, _( "A bionic emits a crackle of noise!" ) );
1328 sfx::play_variant_sound( "bionics", "elec_blast", 100 );
1329 } else {
1330 add_msg_if_player( m_bad, _( "You feel your faulty bionic shuddering." ) );
1331 sfx::play_variant_sound( "bionics", "elec_blast_muffled", 100 );
1332 }
1333 sounds::sound( pos(), 60, sounds::sound_t::movement, _( "Crackle!" ) ); //sfx above
1334 }
1336 get_power_level() >= get_max_power_level() * .75 ) {
1337 mod_str_bonus( -3 );
1338 }
1339 if( has_bionic( bio_trip ) && one_turn_in( 50_minutes ) &&
1342 add_msg_if_player( m_bad, _( "Your vision pixelates!" ) );
1343 add_effect( effect_visuals, 10_minutes );
1344 sfx::play_variant_sound( "bionics", "pixelated", 100 );
1345 }
1346 if( has_bionic( bio_spasm ) && one_turn_in( 5_hours ) && !has_effect( effect_downed ) &&
1349 _( "Your malfunctioning bionic causes you to spasm and fall to the floor!" ),
1350 _( "<npcname> spasms and falls to the floor!" ) );
1351 mod_pain( 1 );
1352 add_effect( effect_stunned, 1_turns );
1353 add_effect( effect_downed, 10_turns, num_bp, 0 );
1354 sfx::play_variant_sound( "bionics", "elec_crackle_high", 100 );
1355 }
1357 one_turn_in( 2_hours ) ) {
1358 add_msg_if_player( m_bad, _( "Your bionics short-circuit, causing you to tremble and shiver." ) );
1360 add_effect( effect_shakes, 5_minutes );
1361 sfx::play_variant_sound( "bionics", "elec_crackle_med", 100 );
1362 }
1363 if( has_bionic( bio_leaky ) && one_turn_in( 6_minutes ) ) {
1364 mod_healthy_mod( -1, -200 );
1365 }
1366 if( has_bionic( bio_sleepy ) && one_turn_in( 50_minutes ) && !in_sleep_state() ) {
1367 mod_fatigue( 1 );
1368 }
1369 if( has_bionic( bio_itchy ) && one_turn_in( 50_minutes ) && !has_effect( effect_formication ) &&
1371 add_msg_if_player( m_bad, _( "Your malfunctioning bionic itches!" ) );
1372 body_part bp = random_body_part( true );
1373 add_effect( effect_formication, 10_minutes, bp );
1374 }
1375 if( has_bionic( bio_glowy ) && !has_effect( effect_glowy_led ) && one_turn_in( 50_minutes ) &&
1377 add_msg_if_player( m_bad, _( "Your malfunctioning bionic starts to glow!" ) );
1378 add_effect( effect_glowy_led, 5_minutes );
1380 }
1381}
body_part random_body_part(bool main_parts_only)
Returns a random body_part token.
Definition: bodypart.cpp:366
void do_player_death_hurt(const player &target, bool death)
Definition: sounds.cpp:1631
static const bionic_id bio_shakes("bio_shakes")
static const efftype_id effect_glowy_led("glowy_led")
static const efftype_id effect_downed("downed")
static const bionic_id bio_power_weakness("bio_power_weakness")
static const bionic_id bio_dis_shock("bio_dis_shock")
static const bionic_id bio_glowy("bio_glowy")
static const efftype_id effect_visuals("visuals")
static const bionic_id bio_trip("bio_trip")
static const bionic_id bio_dis_acid("bio_dis_acid")
static const itype_id itype_e_handcuffs("e_handcuffs")
static const bionic_id bio_spasm("bio_spasm")
static const bionic_id bio_sleepy("bio_sleepy")
static const bionic_id bio_noise("bio_noise")
static const efftype_id effect_formication("formication")
static const bionic_id bio_drain("bio_drain")
static const bionic_id bio_itchy("bio_itchy")
static const bionic_id bio_leaky("bio_leaky")

References _, Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), bio_dis_acid, bio_dis_shock, bio_drain, bio_glowy, bio_itchy, bio_leaky, bio_noise, bio_power_weakness, bio_shakes, bio_sleepy, bio_spasm, bio_trip, item::charges, sfx::do_player_death_hurt(), effect_downed, effect_formication, effect_glowy_led, effect_narcosis, effect_shakes, effect_stunned, effect_visuals, g, get_max_power_level(), get_power_level(), has_bionic(), Creature::has_effect(), has_max_power(), hurtall(), in_sleep_state(), is_deaf(), itype_e_handcuffs, m_bad, m_good, m_warning, mod_fatigue(), mod_healthy_mod(), mod_pain(), mod_power_level(), mod_str_bonus(), sounds::movement, Creature::moves, num_bp, one_turn_in(), sfx::play_variant_sound(), pos(), bionic_data::power_trigger, primary_weapon(), random_body_part(), rng(), sounds::sound(), item::tname(), and item::typeId().

Referenced by suffer().

◆ suffer_from_chemimbalance()

void Character::suffer_from_chemimbalance ( )
private

Definition at line 371 of file suffer.cpp.

372{
373 if( one_turn_in( 6_hours ) && !has_trait( trait_NOPAIN ) ) {
374 add_msg_if_player( m_bad, _( "You suddenly feel sharp pain for no reason." ) );
375 mod_pain( 3 * rng( 1, 3 ) );
376 }
377 if( one_turn_in( 6_hours ) ) {
378 int pkilladd = 5 * rng( -1, 2 );
379 if( pkilladd > 0 ) {
380 add_msg_if_player( m_bad, _( "You suddenly feel numb." ) );
381 } else if( ( pkilladd < 0 ) && ( !( has_trait( trait_NOPAIN ) ) ) ) {
382 add_msg_if_player( m_bad, _( "You suddenly ache." ) );
383 }
384 mod_painkiller( pkilladd );
385 }
386 if( one_turn_in( 6_hours ) && !has_effect( effect_sleep ) ) {
387 add_msg_if_player( m_bad, _( "You feel dizzy for a moment." ) );
388 moves -= rng( 10, 30 );
389 }
390 if( one_turn_in( 6_hours ) ) {
391 int hungadd = 5 * rng( -1, 3 );
392 if( hungadd > 0 ) {
393 add_msg_if_player( m_bad, _( "You suddenly feel hungry." ) );
394 } else {
395 add_msg_if_player( m_good, _( "You suddenly feel a little full." ) );
396 }
397 mod_stored_kcal( -10 * hungadd );
398 }
399 if( one_turn_in( 6_hours ) ) {
400 add_msg_if_player( m_bad, _( "You suddenly feel thirsty." ) );
401 mod_thirst( 5 * rng( 1, 3 ) );
402 }
403 if( one_turn_in( 6_hours ) ) {
404 add_msg_if_player( m_good, _( "You feel fatigued all of a sudden." ) );
405 mod_fatigue( 10 * rng( 2, 4 ) );
406 }
407 if( one_turn_in( 8_hours ) ) {
408 if( one_in( 3 ) ) {
410 } else {
411 add_morale( MORALE_FEELING_BAD, -20, -100 );
412 }
413 }
414 if( one_turn_in( 6_hours ) ) {
415 if( one_in( 3 ) ) {
416 add_msg_if_player( m_bad, _( "You suddenly feel very cold." ) );
418 } else {
419 add_msg_if_player( m_bad, _( "You suddenly feel cold." ) );
420 temp_cur.fill( BODYTEMP_COLD );
421 }
423 }
424 if( one_turn_in( 6_hours ) ) {
425 if( one_in( 3 ) ) {
426 add_msg_if_player( m_bad, _( "You suddenly feel very hot." ) );
428 } else {
429 add_msg_if_player( m_bad, _( "You suddenly feel hot." ) );
430 temp_cur.fill( BODYTEMP_HOT );
431 }
433 }
434}
static const trait_id trait_NOPAIN("NOPAIN")

References _, add_morale(), Creature::add_msg_if_player(), BODYTEMP_COLD, BODYTEMP_HOT, BODYTEMP_NORM, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, bp_eyes, effect_sleep, Creature::has_effect(), has_trait(), m_bad, m_good, mod_fatigue(), mod_pain(), mod_painkiller(), mod_stored_kcal(), mod_thirst(), MORALE_FEELING_BAD, MORALE_FEELING_GOOD, Creature::moves, one_in(), one_turn_in(), rng(), temp_cur, and trait_NOPAIN.

Referenced by suffer_while_awake().

◆ suffer_from_other_mutations()

void Character::suffer_from_other_mutations ( )
private

Definition at line 1036 of file suffer.cpp.

1037{
1038 map &here = get_map();
1039 if( has_trait( trait_SHARKTEETH ) && one_turn_in( 24_hours ) ) {
1040 add_msg_if_player( m_neutral, _( "You shed a tooth!" ) );
1041 here.spawn_item( pos(), "bone", 1 );
1042 }
1043
1045 //~Sound of buzzing Insect Wings
1046 sounds::sound( pos(), 10, sounds::sound_t::movement, _( "BZZZZZ" ), false, "misc",
1047 "insect_wings" );
1048 }
1049
1050 bool wearing_shoes = is_wearing_shoes( side::LEFT ) || is_wearing_shoes( side::RIGHT );
1051 int root_vitamins = 0;
1052 int root_water = 0;
1053 if( has_trait( trait_ROOTS3 ) && here.has_flag( flag_PLOWABLE, pos() ) && !wearing_shoes ) {
1054 root_vitamins += 1;
1056 root_water += 51;
1057 }
1058 }
1059
1060 if( x_in_y( root_vitamins, 576 ) ) {
1061 vitamin_mod( vitamin_id( "iron" ), 1, true );
1062 vitamin_mod( vitamin_id( "calcium" ), 1, true );
1063 mod_healthy_mod( 5, 50 );
1064 }
1065
1066 if( x_in_y( root_water, 2550 ) ) {
1067 // Plants draw some crazy amounts of water from the ground in real life,
1068 // so these numbers try to reflect that uncertain but large amount
1069 // this should take 12 hours to meet your daily needs with ROOTS2, and 8 with ROOTS3
1070 mod_thirst( -1 );
1071 }
1072
1073 if( has_trait( trait_SORES ) ) {
1074 for( const body_part bp : all_body_parts ) {
1075 if( bp == bp_head ) {
1076 continue;
1077 }
1078 int sores_pain = 5 + 0.4 * std::abs( encumb( bp ) );
1079 if( get_pain() < sores_pain ) {
1080 set_pain( sores_pain );
1081 }
1082 }
1083 }
1084 //Web Weavers...weave web
1086 // this adds intensity to if its not already there.
1087 here.add_field( pos(), fd_web, 1 );
1088
1089 }
1090
1091 // Blind/Deaf for brief periods about once an hour,
1092 // and visuals about once every 30 min.
1093 if( has_trait( trait_PER_SLIME ) ) {
1094 if( one_turn_in( 1_hours ) && !has_effect( effect_deaf ) ) {
1095 add_msg_if_player( m_bad, _( "Suddenly, you can't hear anything!" ) );
1096 add_effect( effect_deaf, rng( 20_minutes, 60_minutes ) );
1097 }
1098 if( one_turn_in( 1_hours ) && !( has_effect( effect_blind ) ) ) {
1099 add_msg_if_player( m_bad, _( "Suddenly, your eyes stop working!" ) );
1100 add_effect( effect_blind, rng( 2_minutes, 6_minutes ) );
1101 }
1102 // Yes, you can be blind and hallucinate at the same time.
1103 // Your post-human biology is truly remarkable.
1104 if( one_turn_in( 30_minutes ) && !( has_effect( effect_visuals ) ) ) {
1105 add_msg_if_player( m_bad, _( "Your visual centers must be acting up…" ) );
1106 add_effect( effect_visuals, rng( 36_minutes, 72_minutes ) );
1107 }
1108 }
1109
1110 if( has_trait( trait_WEB_SPINNER ) && !in_vehicle && one_in( 3 ) ) {
1111 // this adds intensity to if its not already there.
1112 here.add_field( pos(), fd_web, 1 );
1113 }
1114
1115 bool should_mutate = has_trait( trait_UNSTABLE ) && !has_trait( trait_CHAOTIC_BAD ) &&
1116 one_turn_in( 48_hours );
1117 should_mutate |= ( has_trait( trait_CHAOTIC ) || has_trait( trait_CHAOTIC_BAD ) ) &&
1118 one_turn_in( 12_hours );
1119 if( should_mutate ) {
1120 mutate();
1121 }
1122
1123 const bool needs_fire = !has_morale( MORALE_PYROMANIA_NEARFIRE ) &&
1125 if( has_trait( trait_PYROMANIA ) && needs_fire && !in_sleep_state() &&
1126 calendar::once_every( 2_hours ) ) {
1127 add_morale( MORALE_PYROMANIA_NOFIRE, -1, -30, 24_hours, 24_hours, true );
1128 if( calendar::once_every( 4_hours ) ) {
1129 const translation smokin_hot_fiyah =
1130 SNIPPET.random_from_category( "pyromania_withdrawal" ).value_or( translation() );
1131 add_msg_if_player( m_bad, "%s", smokin_hot_fiyah );
1132 }
1133 }
1135 calendar::once_every( 2_hours ) ) {
1137 const translation snip = SNIPPET.random_from_category( "killer_withdrawal" ).value_or(
1138 translation() );
1139 add_msg_if_player( m_bad, "%s", snip );
1140 }
1141 add_morale( MORALE_KILLER_NEED_TO_KILL, -1, -30, 24_hours, 24_hours );
1142 }
1143}
bool has_morale(const morale_type &type) const
Definition: character.cpp:9104
void spawn_item(const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
Definition: map.cpp:4313
const morale_type MORALE_KILLER_HAS_KILLED("morale_killer_has_killed")
const morale_type MORALE_PYROMANIA_STARTFIRE("morale_pyromania_startfire")
const morale_type MORALE_KILLER_NEED_TO_KILL("morale_killer_need_to_kill")
const morale_type MORALE_PYROMANIA_NEARFIRE("morale_pyromania_nearfire")
const morale_type MORALE_PYROMANIA_NOFIRE("morale_pyromania_nofire")
static const trait_id trait_PER_SLIME("PER_SLIME")
static const trait_id trait_SHARKTEETH("SHARKTEETH")
static const trait_id trait_CHAOTIC("CHAOTIC")
static const trait_id trait_UNSTABLE("UNSTABLE")
static const trait_id trait_PYROMANIA("PYROMANIA")
static const efftype_id effect_deaf("deaf")
static const trait_id trait_WEB_WEAVER("WEB_WEAVER")
static const trait_id trait_CHAOTIC_BAD("CHAOTIC_BAD")
static const trait_id trait_WINGS_INSECT("WINGS_INSECT")
static const trait_id trait_SORES("SORES")
static const trait_id trait_KILLER("KILLER")
static const trait_id trait_WEB_SPINNER("WEB_SPINNER")
static const std::string flag_PLOWABLE("PLOWABLE")
static const trait_id trait_ROOTS3("ROOTS3")

References _, Creature::add_effect(), map::add_field(), add_morale(), Creature::add_msg_if_player(), all_body_parts, bp_head, effect_blind, effect_deaf, effect_visuals, encumb(), fd_web, flag_PLOWABLE(), get_map(), Creature::get_pain(), get_thirst(), has_active_mutation(), Creature::has_effect(), map::has_flag(), has_morale(), has_trait(), in_sleep_state(), in_vehicle, is_wearing_shoes(), LEFT, m_bad, m_neutral, mod_healthy_mod(), mod_thirst(), MORALE_KILLER_HAS_KILLED, MORALE_KILLER_NEED_TO_KILL, MORALE_PYROMANIA_NEARFIRE, MORALE_PYROMANIA_NOFIRE, MORALE_PYROMANIA_STARTFIRE, sounds::movement, mutate(), calendar::once_every(), one_in(), one_turn_in(), pos(), snippet_library::random_from_category(), RIGHT, rng(), set_pain(), SNIPPET, sounds::sound(), map::spawn_item(), trait_CHAOTIC, trait_CHAOTIC_BAD, trait_KILLER, trait_PER_SLIME, trait_PYROMANIA, trait_ROOTS3, trait_SHARKTEETH, trait_SORES, trait_UNSTABLE, trait_WEB_SPINNER, trait_WEB_WEAVER, trait_WINGS_INSECT, turgid, vitamin_mod(), and x_in_y().

Referenced by suffer().

◆ suffer_from_radiation()

void Character::suffer_from_radiation ( )
private

Definition at line 1145 of file suffer.cpp.

1146{
1147 map &here = get_map();
1148 // checking for radioactive items in inventory
1149 const int item_radiation = leak_level( "RADIOACTIVE" );
1150 const int map_radiation = here.get_radiation( pos() );
1151 float rads = map_radiation / 100.0f + item_radiation / 10.0f;
1152
1153 int rad_mut = 0;
1154 if( has_trait( trait_RADIOACTIVE3 ) ) {
1155 rad_mut = 3;
1156 } else if( has_trait( trait_RADIOACTIVE2 ) ) {
1157 rad_mut = 2;
1158 } else if( has_trait( trait_RADIOACTIVE1 ) ) {
1159 rad_mut = 1;
1160 }
1161
1162 // Spread less radiation when sleeping (slower metabolism etc.)
1163 // Otherwise it can quickly get to the point where you simply can't sleep at all
1164 const bool rad_mut_proc = rad_mut > 0 && x_in_y( rad_mut, to_turns<int>( in_sleep_state() ?
1165 3_hours : 30_minutes ) );
1166
1167 bool has_helmet = false;
1168 const bool power_armored = is_wearing_power_armor( &has_helmet );
1169 const bool rad_resist = power_armored || worn_with_flag( flag_RAD_RESIST );
1170
1171 if( rad_mut > 0 ) {
1172 const bool kept_in = is_rad_immune() || ( rad_resist && !one_in( 4 ) );
1173 if( kept_in ) {
1174 // As if standing on a map tile with radiation level equal to rad_mut
1175 rads += rad_mut / 100.0f;
1176 }
1177
1178 if( rad_mut_proc && !kept_in ) {
1179 // Irradiate a random nearby point
1180 // If you can't, irradiate the player instead
1181 tripoint rad_point = pos() + point( rng( -3, 3 ), rng( -3, 3 ) );
1182 // TODO: Radioactive vehicles?
1183 if( here.get_radiation( rad_point ) < rad_mut ) {
1184 here.adjust_radiation( rad_point, 1 );
1185 } else {
1186 rads += rad_mut;
1187 }
1188 }
1189 }
1190
1191 // Used to control vomiting from radiation to make it not-annoying
1192 bool radiation_increasing = irradiate( rads );
1193
1194 if( radiation_increasing && calendar::once_every( 3_minutes ) && has_bionic( bio_geiger ) ) {
1196 _( "You feel an anomalous sensation coming from "
1197 "your radiation sensors." ) );
1198 }
1199
1200 if( calendar::once_every( 15_minutes ) ) {
1201 if( get_rad() < 0 ) {
1202 set_rad( 0 );
1203 } else if( get_rad() > 2000 ) {
1204 set_rad( 2000 );
1205 }
1206 if( get_option<bool>( "RAD_MUTATION" ) && rng( 100, 10000 ) < get_rad() ) {
1207 mutate();
1208 mod_rad( -50 );
1209 } else if( get_rad() > 50 && rng( 1, 3000 ) < get_rad() && ( stomach.get_calories() > 0 ||
1210 radiation_increasing || !in_sleep_state() ) ) {
1211 vomit();
1212 mod_rad( -1 );
1213 }
1214 }
1215
1216 const bool radiogenic = has_trait( trait_RADIOGENIC );
1217 if( radiogenic && calendar::once_every( 30_minutes ) && get_rad() > 0 ) {
1218 // At 200 irradiation, twice as fast as REGEN
1219 if( x_in_y( get_rad(), 200 ) ) {
1220 healall( 1 );
1221 if( rad_mut == 0 ) {
1222 // Don't heal radiation if we're generating it naturally
1223 // That would counter the main downside of radioactivity
1224 mod_rad( -5 );
1225 }
1226 }
1227 }
1228
1229 if( !radiogenic && get_rad() > 0 ) {
1230 // Even if you heal the radiation itself, the damage is done.
1231 const int hmod = get_healthy_mod();
1232 if( hmod > 200 - get_rad() ) {
1233 set_healthy_mod( std::max( -200, 200 - get_rad() ) );
1234 }
1235 }
1236
1237 if( get_rad() > 200 && calendar::once_every( 10_minutes ) && x_in_y( get_rad(), 1000 ) ) {
1238 hurtall( 1, nullptr );
1239 mod_rad( -5 );
1240 }
1241
1242 // Microreactor CBM
1243 const itype_id &plut_cell = item( "plut_cell" ).typeId();
1244 if( get_fuel_type_available( plut_cell ) > 0 ) {
1245 if( calendar::once_every( 60_minutes ) ) {
1246 int rad_mod = 0;
1247 rad_mod += has_bionic( bio_reactor ) ? 3 : 0;
1248 rad_mod += has_bionic( bio_advreactor ) ? 2 : 0;
1249
1250 if( rad_mod > 1 ) {
1251 mod_rad( rad_mod );
1252 }
1253 }
1254
1255 bool powered_reactor = false;
1256
1257 if( has_bionic( bio_reactor ) ) {
1258 if( get_bionic_state( bio_reactor ).powered ) {
1259 powered_reactor = true;
1260 } else {
1261 mod_power_level( 50_J );
1262 }
1263 }
1264
1265 if( has_bionic( bio_advreactor ) ) {
1266 if( get_bionic_state( bio_advreactor ).powered ) {
1267 powered_reactor = true;
1268 } else {
1269 mod_power_level( 75_J );
1270 }
1271 }
1272
1273 if( has_bionic( bio_reactoroverride ) && powered_reactor ) {
1274 if( get_bionic_state( bio_reactoroverride ).powered ) {
1275 int current_fuel_stock = std::stoi( get_value( plut_cell.str() ) );
1276
1277 current_fuel_stock -= 50;
1278
1279 set_value( plut_cell.str(), std::to_string( current_fuel_stock ) );
1280 update_fuel_storage( plut_cell );
1281
1282 mod_power_level( 40_kJ );
1283 mod_rad( 2 );
1284 }
1285 }
1286 }
1287}
int get_fuel_type_available(const itype_id &fuel) const
Return available space to store specified fuel.
Definition: character.cpp:2025
void adjust_radiation(const tripoint &p, int delta)
Increment the radiation in the given tile by the given delta (decrement it if delta is negative)
Definition: map.cpp:4177
int get_radiation(const tripoint &p) const
Definition: map.cpp:4153
static const bionic_id bio_geiger("bio_geiger")
static const std::string flag_RAD_RESIST("RAD_RESIST")
static const bionic_id bio_reactoroverride("bio_reactoroverride")
static const bionic_id bio_reactor("bio_reactor")
static const bionic_id bio_advreactor("bio_advreactor")

References _, Creature::add_msg_if_player(), map::adjust_radiation(), bio_advreactor, bio_geiger, bio_reactor, bio_reactoroverride, flag_RAD_RESIST(), get_bionic_state(), stomach_contents::get_calories(), get_fuel_type_available(), get_healthy_mod(), get_map(), get_rad(), map::get_radiation(), Creature::get_value(), has_bionic(), has_trait(), healall(), hurtall(), in_sleep_state(), irradiate(), is_rad_immune(), is_wearing_power_armor(), leak_level(), m_warning, mod_power_level(), mod_rad(), mutate(), calendar::once_every(), one_in(), pos(), rng(), set_healthy_mod(), set_rad(), Creature::set_value(), stomach, string_id< T >::str(), to_string(), trait_RADIOACTIVE1, trait_RADIOACTIVE2, trait_RADIOACTIVE3, trait_RADIOGENIC, item::typeId(), update_fuel_storage(), vomit(), worn_with_flag(), and x_in_y().

Referenced by suffer().

◆ suffer_from_schizophrenia()

void Character::suffer_from_schizophrenia ( )
private

Definition at line 436 of file suffer.cpp.

437{
438 std::string i_name_w;
439 item &weapon = primary_weapon();
440 if( !weapon.is_null() ) {
441 i_name_w = weapon.has_var( "item_label" ) ? weapon.get_var( "item_label" ) :
442 //~ %1$s: weapon name
443 string_format( _( "your %1$s" ), weapon.type_name() );
444 }
445 // Start with the effects that both NPCs and avatars can suffer from
446 // Delusions
447 if( one_turn_in( 8_hours ) ) {
448 if( rng( 1, 20 ) > 5 ) { // 75% chance
449 const translation snip = SNIPPET.random_from_category( "schizo_delusion_paranoid" ).value_or(
450 translation() );
451 add_msg_if_player( m_warning, "%s", snip );
452 add_morale( MORALE_FEELING_BAD, -20, -100 );
453 } else { // 25% chance
454 const translation snip = SNIPPET.random_from_category( "schizo_delusion_grandiose" ).value_or(
455 translation() );
456 add_msg_if_player( m_good, "%s", snip );
458 }
459 return;
460 }
461 // Formication
462 if( one_turn_in( 6_hours ) ) {
463 const translation snip = SNIPPET.random_from_category( "schizo_formication" ).value_or(
464 translation() );
465 body_part bp = random_body_part( true );
466 add_effect( effect_formication, 45_minutes, bp );
467 add_msg_if_player( m_bad, "%s", snip );
468 return;
469 }
470 // Numbness
471 if( one_turn_in( 4_hours ) ) {
472 add_msg_if_player( m_bad, _( "You suddenly feel so numb…" ) );
473 mod_painkiller( 25 );
474 return;
475 }
476 // Hallucination
477 if( one_turn_in( 6_hours ) ) {
478 add_effect( effect_hallu, 6_hours );
479 return;
480 }
481 // Visuals
482 if( one_turn_in( 2_hours ) ) {
483 add_effect( effect_visuals, rng( 15_turns, 60_turns ) );
484 return;
485 }
486 // Shaking
487 if( !has_effect( effect_valium ) && one_turn_in( 4_hours ) ) {
488 add_msg_player_or_npc( m_bad, _( "You start to shake uncontrollably." ),
489 _( "<npcname> starts to shake uncontrollably." ) );
490 add_effect( effect_shakes, rng( 2_minutes, 5_minutes ) );
491 return;
492 }
493 // Shout
494 if( one_turn_in( 4_hours ) ) {
495 shout( SNIPPET.random_from_category( "schizo_self_shout" ).value_or( translation() ).translated() );
496 return;
497 }
498 // Drop weapon
499 if( one_turn_in( 2_days ) && !weapon.is_null() ) {
500 const translation snip = SNIPPET.random_from_category( "schizo_weapon_drop" ).value_or(
501 translation() );
502 std::string str = string_format( snip, i_name_w );
503 str[0] = toupper( str[0] );
504
505 add_msg_if_player( m_bad, "%s", str );
506 item_location loc( *this, &weapon );
507 drop( loc, pos() );
508 return;
509 }
510 // Talk to self
511 if( one_turn_in( 4_hours ) ) {
512 const translation snip = SNIPPET.random_from_category( "schizo_self_talk" ).value_or(
513 translation() );
514 add_msg( _( "%1$s says: \"%2$s\"" ), name, snip );
515 return;
516 }
517
518 // effects of this point are entirely internal, so NPCs can't suffer from them
519 if( is_npc() ) {
520 return;
521 }
522 // Sound
523 if( one_turn_in( 4_hours ) ) {
524 sound_hallu();
525 }
526 // Follower turns hostile
527 if( one_turn_in( 4_hours ) ) {
528 std::vector<shared_ptr_fast<npc>> followers = overmap_buffer.get_npcs_near_player( 12 );
529
530 std::string who_gets_angry = name;
531 if( !followers.empty() ) {
532 who_gets_angry = random_entry_ref( followers )->name;
533 }
534 add_msg_if_player( m_bad, _( "%1$s gets angry!" ), who_gets_angry );
535 return;
536 }
537
538 // Monster dies
539 if( one_turn_in( 6_hours ) ) {
540 // TODO: move to monster group json
541 static const std::array<mtype_id, 5> monsters = { {
543 }
544 };
545 add_msg_if_player( _( "%s dies!" ), random_entry_ref( monsters )->nname() );
546 return;
547 }
548
549 // Limb Breaks
550 if( one_turn_in( 4_hours ) ) {
551 const translation snip = SNIPPET.random_from_category( "broken_limb" ).value_or( translation() );
552 add_msg_if_player( m_bad, "%s", snip );
553 return;
554 }
555
556 // NPC chat
557 if( one_turn_in( 4_hours ) ) {
558 std::string i_name = Name::generate( one_in( 2 ) );
559
560 std::string i_talk = SNIPPET.expand( SNIPPET.random_from_category( "<lets_talk>" ).value_or(
561 translation() ).translated() );
562 parse_tags( i_talk, *this, *this );
563
564 add_msg_if_player( _( "%1$s says: \"%2$s\"" ), i_name, i_talk );
565 return;
566 }
567
568 // Skill raise
569 if( one_turn_in( 12_hours ) ) {
570 skill_id raised_skill = Skill::random_skill();
571 add_msg_if_player( m_good, _( "You increase %1$s to level %2$d." ), raised_skill.obj().name(),
572 get_skill_level( raised_skill ) + 1 );
573 return;
574 }
575
576 // Talking weapon
577 if( !weapon.is_null() ) {
578 // If player has a weapon, picks a message from said weapon
579 // Weapon tells player to kill a monster if any are nearby
580 // Weapon is concerned for player if bleeding
581 // Weapon is concerned for itself if damaged
582 // Otherwise random chit-chat
583 std::vector<weak_ptr_fast<monster>> mons = g->all_monsters().items;
584
585 std::string i_talk_w;
586 bool does_talk = false;
587 if( !mons.empty() && one_turn_in( 12_minutes ) ) {
588 std::vector<std::string> seen_mons;
589 for( weak_ptr_fast<monster> &n : mons ) {
590 if( sees( *n.lock() ) ) {
591 seen_mons.emplace_back( n.lock()->get_name() );
592 }
593 }
594 if( !seen_mons.empty() ) {
595 const translation talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_monster" ).value_or(
596 translation() );
597 i_talk_w = string_format( talk_w, random_entry_ref( seen_mons ) );
598 does_talk = true;
599 }
600 }
601 if( !does_talk && has_effect( effect_bleed ) && one_turn_in( 5_minutes ) ) {
602 i_talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_bleeding" ).value_or(
603 translation() ).translated();
604 does_talk = true;
605 } else if( weapon.damage() >= weapon.max_damage() / 3 && one_turn_in( 1_hours ) ) {
606 i_talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_damaged" ).value_or(
607 translation() ).translated();
608 does_talk = true;
609 } else if( one_turn_in( 4_hours ) ) {
610 i_talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_misc" ).value_or(
611 translation() ).translated();
612 does_talk = true;
613 }
614 if( does_talk ) {
615 add_msg_if_player( _( "%1$s says: \"%2$s\"" ), i_name_w, i_talk_w );
616 return;
617 }
618 }
619}
static skill_id random_skill()
Definition: skill.cpp:205
double get_var(const std::string &name, double default_value) const
Definition: item.cpp:1033
int max_damage() const
Maximum amount of damage to an item (state before destroyed)
Definition: item.cpp:6241
bool has_var(const std::string &name) const
Whether the variable is defined at all.
Definition: item.cpp:1078
int damage() const
How much damage has the item sustained?
Definition: item.cpp:699
std::vector< shared_ptr_fast< npc > > get_npcs_near_player(int radius)
Same as get_npcs_near(int,int,int,int) but uses player position as center.
std::string expand(const std::string &str) const
Expand the string by recursively replacing tags in angle brackets (<>) with random snippets from the ...
std::weak_ptr< T > weak_ptr_fast
Definition: memory_fast.h:17
void parse_tags(std::string &phrase, const Character &u, const Character &me, const itype_id &item_type=itype_id::NULL_ID())
Definition: npctalk.cpp:1617
static const mtype_id mon_zombie_cop("mon_zombie_cop")
static const efftype_id effect_hallu("hallu")
static const mtype_id mon_zombie_fireman("mon_zombie_fireman")
static const mtype_id mon_zombie_fat("mon_zombie_fat")
static const mtype_id mon_zombie_soldier("mon_zombie_soldier")
static const mtype_id mon_zombie("mon_zombie")
static const efftype_id effect_valium("valium")

References _, Creature::add_effect(), add_morale(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), item::damage(), drop(), effect_bleed, effect_formication, effect_hallu, effect_shakes, effect_valium, effect_visuals, snippet_library::expand(), g, Name::generate(), overmapbuffer::get_npcs_near_player(), get_skill_level(), item::get_var(), Creature::has_effect(), item::has_var(), Creature::is_npc(), item::is_null(), m_bad, m_good, m_warning, item::max_damage(), mod_painkiller(), mon_zombie, mon_zombie_cop, mon_zombie_fat, mon_zombie_fireman, mon_zombie_soldier, MORALE_FEELING_BAD, MORALE_FEELING_GOOD, name, Skill::name(), string_id< T >::obj(), one_in(), one_turn_in(), overmap_buffer, parse_tags(), pos(), primary_weapon(), random_body_part(), random_entry_ref(), snippet_library::random_from_category(), Skill::random_skill(), rng(), sees(), shout(), SNIPPET, sound_hallu(), string_format(), and item::type_name().

Referenced by suffer_while_awake().

◆ suffer_from_stimulants()

void Character::suffer_from_stimulants ( int  current_stim)
private

Definition at line 1405 of file suffer.cpp.

1406{
1407 // Stim +250 kills
1408 if( current_stim > 210 ) {
1409 if( one_turn_in( 2_minutes ) && !has_effect( effect_downed ) ) {
1410 add_msg_if_player( m_bad, _( "Your muscles spasm!" ) );
1411 if( !has_effect( effect_downed ) ) {
1412 add_msg_if_player( m_bad, _( "You fall to the ground!" ) );
1413 add_effect( effect_downed, rng( 6_turns, 20_turns ) );
1414 }
1415 }
1416 }
1417 if( current_stim > 110 ) {
1418 if( !has_effect( effect_shakes ) && calendar::once_every( 10_minutes ) ) {
1419 add_msg_if_player( _( "You shake uncontrollably." ) );
1420 add_effect( effect_shakes, 15_minutes + 1_turns );
1421 }
1422 }
1423 if( current_stim > 75 ) {
1424 if( calendar::once_every( 5_minutes ) && !has_effect( effect_nausea ) ) {
1425 add_msg_if_player( _( "You feel nauseous…" ) );
1426 add_effect( effect_nausea, 5_minutes );
1427 }
1428 }
1429
1430 //stim -200 or painkillers 240 kills
1431 if( current_stim < -160 || get_painkiller() > 200 ) {
1432 if( one_turn_in( 3_minutes ) && !in_sleep_state() ) {
1433 add_msg_if_player( m_bad, _( "You black out!" ) );
1434 const time_duration dur = rng( 30_minutes, 60_minutes );
1435 add_effect( effect_downed, dur );
1436 fall_asleep( dur );
1437 }
1438 }
1439 if( current_stim < -60 || get_painkiller() > 130 ) {
1440 if( calendar::once_every( 10_minutes ) ) {
1441 add_msg_if_player( m_warning, _( "You feel tired…" ) );
1442 mod_fatigue( rng( 1, 2 ) );
1443 }
1444 }
1445}
static const efftype_id effect_nausea("nausea")

References _, Creature::add_effect(), Creature::add_msg_if_player(), effect_downed, effect_nausea, effect_shakes, fall_asleep(), get_painkiller(), Creature::has_effect(), in_sleep_state(), m_bad, m_warning, mod_fatigue(), calendar::once_every(), one_turn_in(), and rng().

Referenced by suffer().

◆ suffer_from_sunburn()

void Character::suffer_from_sunburn ( )
private

Definition at line 901 of file suffer.cpp.

902{
904 return;
905 }
906
907 std::string sunlight_effect;
909 // Albinism and datura have the same effects, once per minute on average
910 if( !one_turn_in( 1_minutes ) ) {
911 return;
912 }
913 sunlight_effect = _( "The sunlight is really irritating" );
914 } else if( has_trait( trait_SUNBURN ) ) {
915 // Sunburn effects occur about 3 times per minute
916 if( !one_turn_in( 20_seconds ) ) {
917 return;
918 }
919 sunlight_effect = _( "The sunlight burns" );
920 }
921
922 // Sunglasses can keep the sun off the eyes.
923 if( !has_bionic( bio_sunglasses ) &&
924 !( wearing_something_on( bodypart_id( "eyes" ) ) &&
926 add_msg_if_player( m_bad, _( "%s your eyes." ), sunlight_effect );
927 // Pain (1/60) or loss of focus (59/60)
928 if( one_turn_in( 1_minutes ) ) {
929 mod_pain( 1 );
930 } else {
931 focus_pool --;
932 }
933 }
934 // Umbrellas can keep the sun off the skin
935 if( primary_weapon().has_flag( "RAIN_PROTECT" ) ) {
936 return;
937 }
938
939 std::map<bodypart_id, float> bp_exposure = bodypart_exposure();
940
941 // Minimum exposure threshold for pain
942 const float MIN_EXPOSURE = 0.01f;
943 // Count how many body parts are above the threshold
944 int count_affected_bp = 0;
945 // Get the most exposed body part, and how exposed it is. This is to tell the player what body
946 // part is most irritated by sun, so they know what needs to be covered up better.
947 bodypart_id most_exposed_bp;
948 float max_exposure = 0.0f;
949 // Check each bodypart with exposure above the minimum
950 for( const std::pair<const bodypart_id, float> &bp_exp : bp_exposure ) {
951 const float exposure = bp_exp.second;
952 // Skip minimally-exposed parts, and skip the eyes (handled by sunglasses)
953 if( exposure <= MIN_EXPOSURE || bp_exp.first == bodypart_id( "eyes" ) ) {
954 continue;
955 }
956 ++count_affected_bp;
957 if( exposure > max_exposure ) {
958 max_exposure = exposure;
959 most_exposed_bp = bp_exp.first;
960 }
961 }
962
963 // If all body parts are protected, there is no suffering
964 if( count_affected_bp == 0 || !most_exposed_bp ) {
965 return;
966 }
967
968 // Check if both arms/legs are affected
969 int count_limbs = 1;
970 const bodypart_id &other_bp = most_exposed_bp->opposite_part;
971 const bodypart_id &other_bp_rev = other_bp->opposite_part;
972 // If these are different, we have a left/right part like a leg or arm.
973 // If same, it's a central body part with no opposite, like head or torso.
974 // Only used to generate a simpler message when both arms or both legs are affected.
975 if( other_bp != other_bp_rev ) {
976 const auto found = bp_exposure.find( other_bp );
977 // Is opposite part exposed?
978 if( found != bp_exposure.end() && found->second > MIN_EXPOSURE ) {
979 ++count_limbs;
980 }
981 }
982 // Get singular or plural body part name; append "and other body parts" if appropriate
983 std::string bp_name = body_part_name( most_exposed_bp, count_limbs );
984 if( count_affected_bp == count_limbs ) {
985 add_msg_if_player( m_bad, _( "%s your %s." ), sunlight_effect, bp_name );
986 } else {
987 add_msg_if_player( m_bad, _( "%s your %s and other body parts." ), sunlight_effect,
988 bp_name );
989 }
990
991 // Wake up from skin irritation/burning
992 if( has_effect( effect_sleep ) ) {
993 wake_up();
994 }
995
996 // Solar Sensitivity (SUNBURN) trait causes injury to exposed parts
997 if( has_trait( trait_SUNBURN ) ) {
998 mod_pain( 1 );
999 // Check exposure of all body parts
1000 for( const std::pair<const bodypart_id, float> &bp_exp : bp_exposure ) {
1001 const bodypart_id &this_part = bp_exp.first;
1002 const float exposure = bp_exp.second;
1003 // Skip parts with adequate protection
1004 if( exposure <= MIN_EXPOSURE ) {
1005 continue;
1006 }
1007 // Don't damage eyes directly, since it takes from head HP (in other words, your head
1008 // won't be destroyed if only your eyes are exposed).
1009 if( this_part == bodypart_id( "eyes" ) ) {
1010 continue;
1011 }
1012 // Exposure percentage determines likelihood of injury
1013 // 10% exposure is 10% chance of injury, naked = 100% chance
1014 if( x_in_y( exposure, 1.0 ) ) {
1015 // Because hands and feet share an HP pool with arms and legs, and the mouth shares
1016 // an HP pool with the head, those parts take an unfair share of damage in relation
1017 // to the torso, which only has one part. Increase torso damage to balance this.
1018 if( this_part == bodypart_id( "torso" ) ) {
1019 apply_damage( nullptr, this_part, 2 );
1020 } else {
1021 apply_damage( nullptr, this_part, 1 );
1022 }
1023 }
1024 }
1025 } else {
1026 // Albinism/datura causes pain (1/60) or focus loss (59/60)
1027 if( one_turn_in( 1_minutes ) ) {
1028 mod_pain( 1 );
1029 } else {
1030 focus_pool --;
1031 }
1032 }
1033}
std::map< bodypart_id, float > bodypart_exposure()
Map body parts to their total exposure, from 0.0 (fully covered) to 1.0 (buck naked).
Definition: suffer.cpp:874
static const trait_id trait_ALBINO("ALBINO")
static const std::string flag_BLIND("BLIND")
static const trait_id trait_SUNBURN("SUNBURN")
static const std::string flag_SUN_GLASSES("SUN_GLASSES")
static const bionic_id bio_sunglasses("bio_sunglasses")

References _, Creature::add_msg_if_player(), apply_damage(), bio_sunglasses, body_part_name(), bodypart_exposure(), effect_datura, effect_sleep, flag_BLIND(), flag_SUN_GLASSES(), focus_pool, has_bionic(), Creature::has_effect(), Creature::has_flag(), has_trait(), m_bad, mod_pain(), one_turn_in(), primary_weapon(), trait_ALBINO, trait_SUNBURN, wake_up(), wearing_something_on(), worn_with_flag(), and x_in_y().

Referenced by suffer_in_sunlight().

◆ suffer_in_sunlight()

void Character::suffer_in_sunlight ( )
private

Definition at line 809 of file suffer.cpp.

810{
811 double sleeve_factor = armwear_factor();
812 const bool has_hat = wearing_something_on( bodypart_id( "head" ) );
813 const bool leafy = has_trait( trait_LEAVES ) || has_trait( trait_LEAVES2 ) ||
815 const bool leafier = has_trait( trait_LEAVES2 ) || has_trait( trait_LEAVES3 );
816 const bool leafiest = has_trait( trait_LEAVES3 );
817 int sunlight_nutrition = 0;
818 if( leafy && get_map().is_outside( pos() ) && ( g->light_level( pos().z ) >= 40 ) ) {
819 const float weather_factor = ( get_weather().weather_id->sun_intensity >=
820 sun_intensity_type::normal ) ? 1.0 : 0.5;
821 const int player_local_temp = get_weather().get_temperature( pos() );
822 int flux = ( player_local_temp - 65 ) / 2;
823 if( !has_hat ) {
824 sunlight_nutrition += ( 100 + flux ) * weather_factor;
825 }
826 if( leafier ) {
827 int rate = ( ( 100 * sleeve_factor ) + flux ) * 2;
828 sunlight_nutrition += ( rate * ( leafiest ? 2 : 1 ) ) * weather_factor;
829 }
830 }
831
832 if( x_in_y( sunlight_nutrition, 18000 ) ) {
833 vitamin_mod( vitamin_id( "vitA" ), 1, true );
834 vitamin_mod( vitamin_id( "vitC" ), 1, true );
835 }
836
837 if( x_in_y( sunlight_nutrition, 12000 ) ) {
838 mod_stored_kcal( 10 );
839 stomach.ate();
840 }
841
842 if( !g->is_in_sunlight( pos() ) ) {
843 return;
844 }
845
848 }
849
851 get_weather().weather_id->sun_intensity >= sun_intensity_type::high ) {
852 mod_str_bonus( -1 );
853 mod_dex_bonus( -1 );
854 add_miss_reason( _( "The sunlight distracts you." ), 1 );
855 mod_int_bonus( -1 );
856 mod_per_bonus( -1 );
857 }
858 if( has_trait( trait_TROGLO2 ) ) {
859 mod_str_bonus( -1 );
860 mod_dex_bonus( -1 );
861 add_miss_reason( _( "The sunlight distracts you." ), 1 );
862 mod_int_bonus( -1 );
863 mod_per_bonus( -1 );
864 }
865 if( has_trait( trait_TROGLO3 ) ) {
866 mod_str_bonus( -4 );
867 mod_dex_bonus( -4 );
868 add_miss_reason( _( "You can't stand the sunlight!" ), 4 );
869 mod_int_bonus( -4 );
870 mod_per_bonus( -4 );
871 }
872}
void suffer_from_sunburn()
Definition: suffer.cpp:901
double armwear_factor() const
Same as footwear factor, but for arms.
Definition: character.cpp:8925
weather_type_id weather_id
Definition: weather.h:193
sun_intensity_type sun_intensity
Definition: weather_type.h:121
static const trait_id trait_LEAVES("LEAVES")
static const trait_id trait_TROGLO3("TROGLO3")
static const trait_id trait_LEAVES2("LEAVES2")
static const trait_id trait_TROGLO("TROGLO")
static const trait_id trait_TROGLO2("TROGLO2")
static const trait_id trait_LEAVES3("LEAVES3")

References _, add_miss_reason(), armwear_factor(), stomach_contents::ate(), effect_datura, g, get_map(), weather_manager::get_temperature(), get_weather(), Creature::has_effect(), has_trait(), high, mod_dex_bonus(), mod_int_bonus(), mod_per_bonus(), mod_stored_kcal(), mod_str_bonus(), normal, pos(), stomach, suffer_from_sunburn(), weather_type::sun_intensity, trait_ALBINO, trait_LEAVES, trait_LEAVES2, trait_LEAVES3, trait_SUNBURN, trait_TROGLO, trait_TROGLO2, trait_TROGLO3, vitamin_mod(), wearing_something_on(), weather_manager::weather_id, and x_in_y().

Referenced by suffer().

◆ suffer_mutation_power()

void Character::suffer_mutation_power ( const mutation_branch mdata,
char_trait_data tdata 
)
private

Definition at line 207 of file suffer.cpp.

208{
209 if( tdata.powered && tdata.charge > 0 ) {
210 // Already-on units just lose a bit of charge
211 tdata.charge--;
212 } else {
213 // Not-on units, or those with zero charge, have to pay the power cost
214 if( mdata.cooldown > 0 ) {
215 tdata.powered = true;
216 tdata.charge = mdata.cooldown - 1;
217 }
218 if( mdata.hunger ) {
219 // does not directly modify hunger, but burns kcal
220 mod_stored_nutr( mdata.cost );
223 _( "You're too malnourished to keep your %s going." ),
224 mdata.name() );
225 tdata.powered = false;
226 }
227 }
228 if( mdata.thirst ) {
229 mod_thirst( mdata.cost );
230 // Well into Dehydrated
233 _( "You're too dehydrated to keep your %s going." ),
234 mdata.name() );
235 tdata.powered = false;
236 }
237 }
238 if( mdata.fatigue ) {
239 mod_fatigue( mdata.cost );
240 // Exhausted
243 _( "You're too exhausted to keep your %s going." ),
244 mdata.name() );
245 tdata.powered = false;
246 }
247 }
248 if( !tdata.powered ) {
249 apply_mods( mdata.id, false );
250 }
251 }
252}
constexpr float underweight

References _, Creature::add_msg_if_player(), apply_mods(), bmi(), char_trait_data::charge, mutation_branch::cooldown, mutation_branch::cost, dehydrated, exhausted, mutation_branch::fatigue, get_fatigue(), get_thirst(), mutation_branch::hunger, mutation_branch::id, m_warning, mod_fatigue(), mod_stored_nutr(), mod_thirst(), mutation_branch::name(), char_trait_data::powered, mutation_branch::thirst, and character_weight_category::underweight.

Referenced by suffer().

◆ suffer_water_damage()

void Character::suffer_water_damage ( const mutation_branch mdata)
private

suffer() subcalls

Definition at line 187 of file suffer.cpp.

188{
189 for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
190 const float wetness_percentage = static_cast<float>( body_wetness[elem.first->token] ) /
191 drench_capacity[elem.first->token];
192 const int dmg = mdata.weakness_to_water * wetness_percentage;
193 if( dmg > 0 ) {
194 apply_damage( nullptr, elem.first, dmg );
195 add_msg_player_or_npc( m_bad, _( "Your %s is damaged by the water." ),
196 _( "<npcname>'s %s is damaged by the water." ),
197 body_part_name( elem.first ) );
198 } else if( dmg < 0 && elem.second.is_at_max_hp() ) {
199 heal( elem.first, std::abs( dmg ) );
200 add_msg_player_or_npc( m_good, _( "Your %s is healed by the water." ),
201 _( "<npcname>'s %s is healed by the water." ),
202 body_part_name( elem.first ) );
203 }
204 }
205}
int weakness_to_water
maximum damage dealt by water every minute when wet.
Definition: mutation.h:168

References _, Creature::add_msg_player_or_npc(), apply_damage(), body_part_name(), body_wetness, drench_capacity, Creature::get_body(), heal(), m_bad, m_good, and mutation_branch::weakness_to_water.

Referenced by suffer().

◆ suffer_while_awake()

void Character::suffer_while_awake ( int  current_stim)
private

Definition at line 304 of file suffer.cpp.

305{
307 ( weight_carried() > 4 * weight_capacity() ) ) {
308 if( has_effect( effect_downed ) ) {
309 add_effect( effect_downed, 1_turns, num_bp, 0 );
310 } else {
311 add_effect( effect_downed, 2_turns, num_bp, 0 );
312 }
313 }
316 }
320 }
321
323 if( one_turn_in( 8_hours ) ) {
325 _( "You're suddenly overcome with the urge to sleep and you pass out." ),
326 _( "<npcname>'s suddenly passes out." ) );
327 fall_asleep( 20_minutes );
328 }
329 }
330
332 if( current_stim > 50 && one_in( to_turns<int>( 30_minutes ) - ( current_stim * 6 ) ) ) {
333 add_effect( effect_shakes, 30_minutes + 1_turns * current_stim );
334 } else if( ( get_kcal_percent() < 0.95f ) &&
335 one_turn_in( 60_minutes - 1_seconds * ( max_stored_kcal() - get_stored_kcal() ) ) ) {
336 add_effect( effect_shakes, 40_minutes );
337 }
338 }
339
340 if( has_trait( trait_MOODSWINGS ) && one_turn_in( 6_hours ) ) {
341 if( rng( 1, 20 ) > 9 ) {
342 // 55% chance
343 add_morale( MORALE_MOODSWING, -100, -500 );
344 } else {
345 // 45% chance
346 add_morale( MORALE_MOODSWING, 100, 500 );
347 }
348 }
349
350 if( has_trait( trait_VOMITOUS ) && one_turn_in( 7_hours ) ) {
351 vomit();
352 }
353
354 if( has_trait( trait_SHOUT1 ) && one_turn_in( 6_hours ) ) {
355 shout();
356 }
357 if( has_trait( trait_SHOUT2 ) && one_turn_in( 4_hours ) ) {
358 shout();
359 }
360 if( has_trait( trait_SHOUT3 ) && one_turn_in( 3_hours ) ) {
361 shout();
362 }
363 if( has_trait( trait_M_SPORES ) && one_turn_in( 4_hours ) ) {
364 spores();
365 }
366 if( has_trait( trait_M_BLOSSOMS ) && one_turn_in( 3_hours ) ) {
367 blossoms();
368 }
369}
void suffer_from_chemimbalance()
Definition: suffer.cpp:371
void suffer_from_schizophrenia()
Definition: suffer.cpp:436
const morale_type MORALE_MOODSWING("morale_moodswing")
static const trait_id trait_JITTERY("JITTERY")
static const trait_id trait_SHOUT1("SHOUT1")
static const trait_id trait_NARCOLEPTIC("NARCOLEPTIC")
static const efftype_id effect_took_thorazine("took_thorazine")
static const trait_id trait_SHOUT2("SHOUT2")
static const trait_id trait_VOMITOUS("VOMITOUS")
static const trait_id trait_DEBUG_STORAGE("DEBUG_STORAGE")
static const trait_id trait_CHEMIMBALANCE("CHEMIMBALANCE")
static const trait_id trait_M_BLOSSOMS("M_BLOSSOMS")
static const trait_id trait_SHOUT3("SHOUT3")
static const trait_id trait_SCHIZOPHRENIC("SCHIZOPHRENIC")
static const trait_id trait_M_SPORES("M_SPORES")
static const trait_id trait_MOODSWINGS("MOODSWINGS")

References _, Creature::add_effect(), add_morale(), Creature::add_msg_player_or_npc(), AEP_SCHIZO, blossoms(), effect_downed, effect_feral_killed_recently, effect_shakes, effect_took_thorazine, fall_asleep(), get_kcal_percent(), get_stored_kcal(), has_artifact_with(), Creature::has_effect(), has_trait(), m_bad, max_stored_kcal(), MORALE_MOODSWING, num_bp, one_in(), one_turn_in(), rng(), shout(), spores(), suffer_from_chemimbalance(), suffer_from_schizophrenia(), trait_CHEMIMBALANCE, trait_DEBUG_STORAGE, trait_JITTERY, trait_M_BLOSSOMS, trait_M_SPORES, trait_MOODSWINGS, trait_NARCOLEPTIC, trait_SCHIZOPHRENIC, trait_SHOUT1, trait_SHOUT2, trait_SHOUT3, trait_VOMITOUS, vomit(), weight_capacity(), and weight_carried().

Referenced by suffer().

◆ suffer_while_underwater()

void Character::suffer_while_underwater ( )
private

Definition at line 254 of file suffer.cpp.

255{
257 oxygen--;
258 }
259 if( oxygen < 12 && worn_with_flag( "REBREATHER" ) ) {
260 oxygen += 12;
261 }
262 if( oxygen <= 5 ) {
264 oxygen += 5;
266 } else {
267 add_msg_if_player( m_bad, _( "You're drowning!" ) );
268 apply_damage( nullptr, bodypart_id( "torso" ), rng( 1, 4 ) );
269 }
270 }
271 if( has_trait( trait_FRESHWATEROSMOSIS ) && !get_map().has_flag_ter( "SALT_WATER", pos() ) &&
273 mod_thirst( -1 );
274 }
275}
static const trait_id trait_FRESHWATEROSMOSIS("FRESHWATEROSMOSIS")
static const trait_id trait_GILLS_CEPH("GILLS_CEPH")
static const trait_id trait_GILLS("GILLS")

References _, Creature::add_msg_if_player(), apply_damage(), bio_gills, get_map(), get_power_level(), get_thirst(), has_bionic(), has_trait(), m_bad, mod_power_level(), mod_thirst(), oxygen, pos(), bionic_data::power_trigger, rng(), trait_FRESHWATEROSMOSIS, trait_GILLS, trait_GILLS_CEPH, turgid, and worn_with_flag().

Referenced by suffer().

◆ suffer_without_sleep()

void Character::suffer_without_sleep ( int  sleep_deprivation)
private

Definition at line 1447 of file suffer.cpp.

1448{
1449 if( has_effect( effect_meth ) ) {
1450 return;
1451 }
1452 // redo as a snippet?
1454 if( one_turn_in( 50_minutes ) ) {
1455 switch( dice( 1, 4 ) ) {
1456 default:
1457 case 1:
1458 add_msg_player_or_npc( m_warning, _( "You tiredly rub your eyes." ),
1459 _( "<npcname> tiredly rubs their eyes." ) );
1460 break;
1461 case 2:
1462 add_msg_player_or_npc( m_warning, _( "You let out a small yawn." ),
1463 _( "<npcname> lets out a small yawn." ) );
1464 break;
1465 case 3:
1466 add_msg_player_or_npc( m_warning, _( "You stretch your back." ),
1467 _( "<npcname> stretches their back." ) );
1468 break;
1469 case 4:
1470 add_msg_player_or_npc( m_warning, _( "You feel mentally tired." ),
1471 _( "<npcname> lets out a huge yawn." ) );
1472 break;
1473 }
1474 }
1475 }
1476 // Minor discomfort
1478 if( one_turn_in( 75_minutes ) ) {
1479 add_msg_if_player( m_warning, _( "You feel lightheaded for a moment." ) );
1480 moves -= 10;
1481 }
1482 if( one_turn_in( 100_minutes ) ) {
1483 add_msg_if_player( m_warning, _( "Your muscles spasm uncomfortably." ) );
1484 mod_pain( 2 );
1485 }
1486 if( !has_effect( effect_visuals ) && one_turn_in( 150_minutes ) ) {
1487 add_msg_if_player( m_warning, _( "Your vision blurs a little." ) );
1488 add_effect( effect_visuals, rng( 1_minutes, 5_minutes ) );
1489 }
1490 }
1491 // Slight disability
1493 if( one_turn_in( 75_minutes ) ) {
1494 add_msg_if_player( m_bad, _( "Your mind lapses into unawareness briefly." ) );
1495 moves -= rng( 20, 80 );
1496 }
1497 if( one_turn_in( 125_minutes ) ) {
1498 add_msg_if_player( m_bad, _( "Your muscles ache in stressfully unpredictable ways." ) );
1499 mod_pain( rng( 2, 10 ) );
1500 }
1501 if( one_turn_in( 5_hours ) ) {
1502 add_msg_if_player( m_bad, _( "You have a distractingly painful headache." ) );
1503 mod_pain( rng( 10, 25 ) );
1504 }
1505 }
1506 // Major disability, high chance of passing out also relevant
1508 if( !has_effect( effect_nausea ) && one_turn_in( 500_minutes ) ) {
1509 add_msg_if_player( m_bad, _( "You feel heartburn and an acid taste in your mouth." ) );
1510 mod_pain( 5 );
1511 add_effect( effect_nausea, rng( 5_minutes, 30_minutes ) );
1512 }
1513 if( one_turn_in( 5_hours ) ) {
1514 add_msg_if_player( m_bad, _( "Your mind is so tired that you feel you can't trust "
1515 "your eyes anymore." ) );
1516 add_effect( effect_hallu, rng( 5_minutes, 60_minutes ) );
1517 }
1518 if( !has_effect( effect_shakes ) && one_turn_in( 425_minutes ) ) {
1519 add_msg_if_player( m_bad, _( "Your muscles spasm uncontrollably, and you have "
1520 "trouble keeping your balance." ) );
1521 add_effect( effect_shakes, 15_minutes );
1522 } else if( has_effect( effect_shakes ) && one_turn_in( 75_seconds ) ) {
1523 moves -= 10;
1524 add_msg_player_or_npc( m_warning, _( "Your shaking legs make you stumble." ),
1525 _( "<npcname> stumbles." ) );
1526 if( !has_effect( effect_downed ) && one_in( 10 ) ) {
1527 add_msg_player_or_npc( m_bad, _( "You fall over!" ), _( "<npcname> falls over!" ) );
1528 add_effect( effect_downed, rng( 3_turns, 10_turns ) );
1529 }
1530 }
1531 }
1532}
static const efftype_id effect_meth("meth")

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), dice(), effect_downed, effect_hallu, effect_meth, effect_nausea, effect_shakes, effect_visuals, harmless, Creature::has_effect(), m_bad, m_warning, major, minor, mod_pain(), Creature::moves, one_in(), one_turn_in(), rng(), serious, and sleep_deprivation.

Referenced by suffer().

◆ swim_speed()

int Character::swim_speed ( ) const

Returns the player's speed for swimming across water tiles.

Strength increases swim speed bonus from PAWS Strength increases swim speed bonus from PAWS_LARGE Strength increases swim speed bonus from swim_fins Strength increases swim speed bonus from WEBBED Swimming increases swim speed Strength increases swim speed Dexterity increases swim speed

Definition at line 817 of file character.cpp.

818{
819 int ret;
820 if( is_mounted() ) {
821 monster *mon = mounted_creature.get();
822 // no difference in swim speed by monster type yet.
823 // TODO: difference in swim speed by monster type.
824 // No monsters are currently mountable and can swim, though mods may allow this.
825 if( mon->swims() ) {
826 ret = 25;
827 ret += get_weight() / 120_gram - 50 * mon->get_size();
828 return ret;
829 }
830 }
831 const auto usable = exclusive_flag_coverage( "ALLOWS_NATURAL_ATTACKS" );
832 float hand_bonus_mult = ( usable.test( bp_hand_l ) ? 0.5f : 0.0f ) +
833 ( usable.test( bp_hand_r ) ? 0.5f : 0.0f );
834
835 // base swim speed.
836 ret = ( 440 * mutation_value( "movecost_swim_modifier" ) ) + weight_carried() /
837 ( 60_gram / mutation_value( "movecost_swim_modifier" ) ) - 50 * get_skill_level( skill_swimming );
838 /** @EFFECT_STR increases swim speed bonus from PAWS */
839 if( has_trait( trait_PAWS ) ) {
840 ret -= hand_bonus_mult * ( 20 + str_cur * 3 );
841 }
842 /** @EFFECT_STR increases swim speed bonus from PAWS_LARGE */
843 if( has_trait( trait_PAWS_LARGE ) ) {
844 ret -= hand_bonus_mult * ( 20 + str_cur * 4 );
845 }
846 /** @EFFECT_STR increases swim speed bonus from swim_fins */
847 if( worn_with_flag( "FIN", bodypart_id( "foot_l" ) ) ||
848 worn_with_flag( "FIN", bodypart_id( "foot_r" ) ) ) {
849 if( worn_with_flag( "FIN", bodypart_id( "foot_l" ) ) &&
850 worn_with_flag( "FIN", bodypart_id( "foot_r" ) ) ) {
851 ret -= ( 15 * str_cur );
852 } else {
853 ret -= ( 15 * str_cur ) / 2;
854 }
855 }
856 /** @EFFECT_STR increases swim speed bonus from WEBBED */
857 if( has_trait( trait_WEBBED ) ) {
858 ret -= hand_bonus_mult * ( 60 + str_cur * 5 );
859 }
860 /** @EFFECT_SWIMMING increases swim speed */
861 ret += ( 50 - get_skill_level( skill_swimming ) * 2 ) * ( ( encumb( bp_leg_l ) + encumb(
862 bp_leg_r ) ) / 10 );
863 ret += ( 80 - get_skill_level( skill_swimming ) * 3 ) * ( encumb( bp_torso ) / 10 );
864 if( get_skill_level( skill_swimming ) < 10 ) {
865 for( auto &i : worn ) {
866 ret += i.volume() / 125_ml * ( 10 - get_skill_level( skill_swimming ) );
867 }
868 }
869 /** @EFFECT_STR increases swim speed */
870
871 /** @EFFECT_DEX increases swim speed */
872 ret -= str_cur * 6 + dex_cur * 4;
873 if( worn_with_flag( "FLOTATION" ) ) {
874 ret = std::min( ret, 400 );
875 ret = std::max( ret, 200 );
876 }
877 // If (ret > 500), we can not swim; so do not apply the underwater bonus.
878 if( is_underwater() && ret < 500 ) {
879 ret -= 50;
880 }
881
882 // Running movement mode while swimming means faster swim style, like crawlstroke
883 if( move_mode == CMM_RUN ) {
884 ret -= 80;
885 }
886 // Crouching movement mode while swimming means slower swim style, like breaststroke
887 if( move_mode == CMM_CROUCH ) {
888 ret += 50;
889 }
890
891 if( ret < 30 ) {
892 ret = 30;
893 }
894 return ret;
895}
static const skill_id skill_swimming("swimming")
static const trait_id trait_WEBBED("WEBBED")
static const trait_id trait_PAWS_LARGE("PAWS_LARGE")
static const trait_id trait_PAWS("PAWS")
bool swims() const
Definition: monster.cpp:951

References bp_hand_l, bp_hand_r, bp_leg_l, bp_leg_r, bp_torso, CMM_CROUCH, CMM_RUN, dex_cur, encumb(), exclusive_flag_coverage(), monster::get_size(), get_skill_level(), get_weight(), has_trait(), is_mounted(), Creature::is_underwater(), mounted_creature, move_mode, mutation_value(), cata::hash64_detail::ret, skill_swimming, str_cur, monster::swims(), trait_PAWS, trait_PAWS_LARGE, trait_WEBBED, weight_carried(), worn, and worn_with_flag().

Referenced by avatar_action::move(), avatar_action::swim(), and game::vertical_move().

◆ switch_mutations()

void Character::switch_mutations ( const trait_id switched,
const trait_id target,
bool  start_powered 
)

Unset switched mutation and set target mutation instead.

Definition at line 182 of file mutation.cpp.

184{
185 unset_mutation( switched );
186 mutation_loss_effect( switched );
187
188 set_mutation( target );
189 my_mutations[target].powered = start_powered;
190 mutation_effect( target );
191}

References mutation_effect(), mutation_loss_effect(), my_mutations, set_mutation(), and unset_mutation().

Referenced by activate_mutation(), and deactivate_mutation().

◆ symbol()

const std::string & Character::symbol ( ) const
overridevirtual

Implements Creature.

Definition at line 540 of file character.cpp.

541{
542 static const std::string character_symbol( "@" );
543 return character_symbol;
544}

Referenced by anonymous_namespace{animation.cpp}::draw_hit_player_curses(), and avatar::memorize_symbol().

◆ symbol_color()

nc_color Character::symbol_color ( ) const
overridevirtual

Implements Creature.

Definition at line 6041 of file character.cpp.

6042{
6043 nc_color basic = basic_symbol_color();
6044
6045 if( has_effect( effect_downed ) ) {
6046 return hilite( basic );
6047 } else if( has_effect( effect_grabbed ) ) {
6048 return cyan_background( basic );
6049 }
6050
6051 const auto &fields = get_map().field_at( pos() );
6052
6053 // Priority: electricity, fire, acid, gases
6054 bool has_elec = false;
6055 bool has_fire = false;
6056 bool has_acid = false;
6057 bool has_fume = false;
6058 for( const auto &field : fields ) {
6059 has_elec = field.first.obj().has_elec;
6060 if( has_elec ) {
6061 return hilite( basic );
6062 }
6063 has_fire = field.first.obj().has_fire;
6064 has_acid = field.first.obj().has_acid;
6065 has_fume = field.first.obj().has_fume;
6066 }
6067 if( has_fire ) {
6068 return red_background( basic );
6069 }
6070 if( has_acid ) {
6071 return green_background( basic );
6072 }
6073 if( has_fume ) {
6074 return white_background( basic );
6075 }
6076 if( in_sleep_state() ) {
6077 return hilite( basic );
6078 }
6079 return basic;
6080}
nc_color basic_symbol_color() const override
Definition: character.cpp:6011
A variable sized collection of field entries on a given map square.
Definition: field.h:131
const field & field_at(const tripoint &p) const
Get the fields that are here.
Definition: map.cpp:5419
nc_color white_background(const nc_color &c)
Definition: color.cpp:521
nc_color green_background(const nc_color &c)
Definition: color.cpp:527
nc_color red_background(const nc_color &c)
Definition: color.cpp:515
nc_color cyan_background(const nc_color &c)
Definition: color.cpp:545
nc_color hilite(const nc_color &c)
Definition: color.cpp:509

References basic_symbol_color(), cyan_background(), effect_downed, effect_grabbed, map::field_at(), get_map(), green_background(), Creature::has_effect(), has_fire(), hilite(), in_sleep_state(), pos(), red_background(), and white_background().

Referenced by overmap_ui::draw_ascii(), anonymous_namespace{animation.cpp}::draw_hit_player_curses(), and game::list_monsters().

◆ takeoff()

bool Character::takeoff ( item it,
std::list< item > *  res = nullptr 
)

Take off an item.

May start an activity.

Parameters
itItem to take off
[out]resIf set, moves resulting item into the list.
Returns
true on success

Definition at line 3045 of file character.cpp.

3046{
3047 const auto ret = can_takeoff( it, res );
3048 if( !ret.success() ) {
3049 add_msg( m_info, "%s", ret.c_str() );
3050 return false;
3051 }
3052
3053 auto iter = std::find_if( worn.begin(), worn.end(), [ &it ]( const item & wit ) {
3054 return &it == &wit;
3055 } );
3056
3057 if( res == nullptr ) {
3059 if( is_npc() || query_yn( _( "No room in inventory for your %s. Drop it?" ),
3060 colorize( it.tname(), it.color_in_inventory() ) ) ) {
3061 item_location loc( *this, &it );
3062 drop( loc, pos() );
3063 return true; // the drop activity ends up taking off the item anyway so shouldn't try to do it again here
3064 } else {
3065 return false;
3066 }
3067 }
3068 iter->on_takeoff( *this );
3070 } else {
3071 iter->on_takeoff( *this );
3072 res->push_back( it );
3073 }
3074
3075 add_msg_player_or_npc( _( "You take off your %s." ),
3076 _( "<npcname> takes off their %s." ),
3077 it.tname() );
3078
3079 // TODO: Make this variable
3080 mod_moves( -250 );
3081 worn.erase( iter );
3082
3085
3086 return true;
3087}
units::volume volume_capacity_reduced_by(const units::volume &mod, const excluded_stacks &without={}) const
Definition: character.cpp:2675
nc_color color_in_inventory() const
Returns the color of the item depending on usefulness for the player character, e....
Definition: item.cpp:4147
units::volume get_storage() const
Returns the storage amount (islot_armor::storage) that this item provides when worn.
Definition: item.cpp:5757

References _, inventory::add_item_keep_invlet(), add_msg(), Creature::add_msg_player_or_npc(), can_takeoff(), item::color_in_inventory(), colorize(), drop(), item::get_storage(), inv, Creature::is_npc(), m_info, Creature::mod_moves(), pos(), query_yn(), recalc_sight_limits(), reset_encumbrance(), cata::hash64_detail::ret, item::tname(), item::volume(), volume_capacity_reduced_by(), volume_carried(), and worn.

Referenced by npc::adjust_worn(), pickup::obtain_and_tokenize_items(), examine_item_menu::run(), show_armor_layers_ui(), takeoff(), and npc::wear_if_wanted().

◆ temp_corrected_by_climate_control()

int Character::temp_corrected_by_climate_control ( int  temperature) const

Value of the body temperature corrected by climate control.

Definition at line 9564 of file character.cpp.

9565{
9566 const int variation = int( BODYTEMP_NORM * 0.5 );
9567 if( temperature < BODYTEMP_SCORCHING + variation &&
9568 temperature > BODYTEMP_FREEZING - variation ) {
9571 } else if( temperature > BODYTEMP_VERY_HOT ) {
9573 } else if( temperature > BODYTEMP_HOT ) {
9575 } else if( temperature < BODYTEMP_FREEZING ) {
9577 } else if( temperature < BODYTEMP_VERY_COLD ) {
9579 } else if( temperature < BODYTEMP_COLD ) {
9581 }
9582 }
9583 return temperature;
9584}

References BODYTEMP_COLD, BODYTEMP_FREEZING, BODYTEMP_HOT, BODYTEMP_NORM, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, and BODYTEMP_VERY_HOT.

Referenced by update_bodytemp().

◆ temp_equalizer()

void Character::temp_equalizer ( const bodypart_id bp1,
const bodypart_id bp2 
)

Equalizes heat between body parts.

Definition at line 5710 of file character.cpp.

5711{
5712 // Body heat is moved around.
5713 // If bp1 is warmer, it will lose heat
5714 int diff = static_cast<int>( ( temp_cur[bp2->token] - temp_cur[bp1->token] ) * 0.001 );
5715 temp_cur[bp1->token] += diff;
5716 temp_cur[bp2->token] -= diff;
5717}

References temp_cur.

Referenced by update_bodytemp().

◆ throw_range()

int Character::throw_range ( const item it) const

Maximum thrown range with a given item, taking all active effects into account.

Strength determines maximum weight that can be thrown Strength increases throwing range, vs item weight (high or low) Strength caps throwing range Throw caps throwing range

Definition at line 6199 of file character.cpp.

6200{
6201 if( it.is_null() ) {
6202 return -1;
6203 }
6204
6205 item tmp = it;
6206
6207 if( tmp.count_by_charges() && tmp.charges > 1 ) {
6208 tmp.charges = 1;
6209 }
6210
6211 /** @EFFECT_STR determines maximum weight that can be thrown */
6212 if( ( tmp.weight() / 113_gram ) > static_cast<int>( str_cur * 15 ) ) {
6213 return 0;
6214 }
6215 // Increases as weight decreases until 150 g, then decreases again
6216 /** @EFFECT_STR increases throwing range, vs item weight (high or low) */
6217 int str_override = str_cur;
6218 if( is_mounted() ) {
6219 auto mons = mounted_creature.get();
6220 str_override = mons->mech_str_addition() != 0 ? mons->mech_str_addition() : str_cur;
6221 }
6222 int ret = ( str_override * 10 ) / ( tmp.weight() >= 150_gram ? tmp.weight() / 113_gram : 10 -
6223 static_cast<int>(
6224 tmp.weight() / 15_gram ) );
6225 ret -= tmp.volume() / 1_liter;
6226 static const std::set<material_id> affected_materials = { material_id( "iron" ), material_id( "steel" ) };
6227 if( has_active_bionic( bio_railgun ) && tmp.made_of_any( affected_materials ) ) {
6228 ret *= 2;
6229 }
6230 if( ret < 1 ) {
6231 return 1;
6232 }
6233 // Cap at double our strength + skill
6234 /** @EFFECT_STR caps throwing range */
6235
6236 /** @EFFECT_THROW caps throwing range */
6237 if( ret > str_override * 3 + get_skill_level( skill_throw ) ) {
6238 return str_override * 3 + get_skill_level( skill_throw );
6239 }
6240
6241 return ret;
6242}
static const bionic_id bio_railgun("bio_railgun")
static const skill_id skill_throw("throw")

References bio_railgun, item::charges, item::count_by_charges(), get_skill_level(), has_active_bionic(), is_mounted(), item::is_null(), item::made_of_any(), mounted_creature, cata::hash64_detail::ret, skill_throw, str_cur, item::volume(), and item::weight().

Referenced by npc::alt_attack(), target_handler::mode_throw(), and avatar_action::plthrow().

◆ toggle_trait()

void Character::toggle_trait ( const trait_id trait_)

Toggles a trait on the player and in their mutation list.

Definition at line 125 of file mutation.cpp.

126{
127 // Take copy of argument because it might be a reference into a container
128 // we're about to erase from.
129 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
130 const trait_id trait = trait_;
131 const auto titer = my_traits.find( trait );
132 const auto miter = my_mutations.find( trait );
133 // These shouldn't be inlined, otherwise the sync check uses invalid iterators
134 bool no_trait = titer == my_traits.end();
135 bool no_mutation = miter == my_mutations.end();
136 if( no_trait ) {
137 my_traits.insert( trait );
138 } else {
139 my_traits.erase( titer );
140 }
141 if( no_trait != no_mutation ) {
142 debugmsg( "my_traits and my_mutations were out of sync for %s\n", trait.str() );
143 return;
144 }
145 if( no_mutation ) {
146 set_mutation( trait );
147 } else {
148 unset_mutation( trait );
149 }
150}

References debugmsg, my_mutations, my_traits, set_mutation(), string_id< T >::str(), and unset_mutation().

Referenced by newcharacter::add_traits(), clear_mutations(), avatar::create(), tutorial_game::init(), wish_mutate_callback::key(), avatar::randomize(), npc::randomize(), reset_scenario(), set_profession(), set_traits(), and gun_actor::shoot().

◆ unarmed_attack()

bool Character::unarmed_attack ( ) const

True if unarmed or wielding a weapon with the UNARMED_WEAPON flag.

Definition at line 210 of file melee.cpp.

211{
212 const item &weap = used_weapon();
213 return weap.is_null() || weap.has_flag( "UNARMED_WEAPON" );
214}

References item::has_flag(), item::is_null(), and used_weapon().

Referenced by mattack::copbot(), has_weapon(), conditional_t< T >::set_can_stow_weapon(), and conditional_t< T >::set_has_weapon().

◆ uncanny_dodge()

bool Character::uncanny_dodge ( )
overridevirtual

Handles the uncanny dodge bionic and effects, returns true if the creature successfully dodges.

Reimplemented from Creature.

Definition at line 10656 of file character.cpp.

10657{
10658 return character_funcs::try_uncanny_dodge( *this );
10659}
bool try_uncanny_dodge(Character &who)
Try to execute an uncanny dodge bionic ability.

References character_funcs::try_uncanny_dodge().

Referenced by mattack::grab(), and mattack::science().

◆ unimpaired_range()

int Character::unimpaired_range ( ) const

Returns the player maximum vision range factoring in mutations, diseases, and other effects.

Definition at line 630 of file character.cpp.

631{
632 return std::min( sight_max, 60 );
633}

References sight_max.

Referenced by sees().

◆ uninstall_bionic() [1/2]

bool Character::uninstall_bionic ( const bionic target_cbm,
monster installer,
player patient,
float  adjusted_skill 
)

Used by monster to perform surgery.

Definition at line 2159 of file bionics.cpp.

2161{
2162 if( installer.ammo[itype_anesthetic] <= 0 ) {
2163 if( g->u.sees( installer ) ) {
2164 add_msg( _( "The %s's anesthesia kit looks empty." ), installer.name() );
2165 }
2166 return false;
2167 }
2168
2169 const itype_id itemtype = target_cbm.info().itype();
2170 int difficulty = itemtype.is_valid() ? itemtype->bionic->difficulty : BIONIC_NOITEM_DIFFICULTY;
2171 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty + 2 );
2172 int success = chance_of_success - rng( 1, 100 );
2173
2174 const time_duration duration = difficulty * 20_minutes;
2175 // don't stack up the effect
2176 if( !installer.has_effect( effect_operating ) ) {
2177 installer.add_effect( effect_operating, duration + 5_turns );
2178 }
2179
2180 if( patient.is_player() ) {
2181 add_msg( m_bad,
2182 _( "You feel a tiny pricking sensation in your right arm, and lose all sensation before abruptly blacking out." ) );
2183 } else if( g->u.sees( installer ) ) {
2184 add_msg( m_bad,
2185 _( "The %1$s gently inserts a syringe into %2$s's arm and starts injecting something while holding them down." ),
2186 installer.name(), patient.disp_name() );
2187 }
2188
2189 installer.ammo[itype_anesthetic] -= 1;
2190
2191 patient.add_effect( effect_narcosis, duration );
2192 patient.add_effect( effect_sleep, duration );
2193
2194 if( patient.is_player() ) {
2195 add_msg( _( "You fall asleep and %1$s starts operating." ), installer.disp_name() );
2196 } else if( g->u.sees( patient ) ) {
2197 add_msg( _( "%1$s falls asleep and %2$s starts operating." ), patient.disp_name(),
2198 installer.disp_name() );
2199 }
2200
2201 if( success > 0 ) {
2202
2203 if( patient.is_player() ) {
2204 add_msg( m_neutral, _( "Your parts are jiggled back into their familiar places." ) );
2205 add_msg( m_mixed, _( "Successfully removed %s." ), target_cbm.info().name );
2206 } else if( patient.is_npc() && g->u.sees( patient ) ) {
2207 add_msg( m_neutral, _( "%s's parts are jiggled back into their familiar places." ),
2208 patient.disp_name() );
2209 add_msg( m_mixed, _( "Successfully removed %s." ), target_cbm.info().name );
2210 }
2211
2212 // remove power bank provided by bionic
2213 patient.mod_max_power_level( -target_cbm.info().capacity );
2214 patient.remove_bionic( target_cbm.id );
2215 const itype_id iid = itemtype.is_valid() &&
2216 !target_cbm.info().has_flag( flag_BIONIC_FAULTY ) ? itemtype : itype_burnt_out_bionic;
2218 if( itemtype.is_valid() ) {
2219 cbm.faults.emplace( fault_bionic_nonsterile );
2220 }
2221 get_map().add_item( patient.pos(), cbm );
2222 } else {
2223 bionics_uninstall_failure( installer, patient, difficulty, success, adjusted_skill );
2224 }
2225
2226 return false;
2227}
static const efftype_id effect_sleep("sleep")
static const efftype_id effect_operating("operating")
static const itype_id itype_anesthetic("anesthetic")
std::map< itype_id, int > ammo
Definition: monster.h:512
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Definition: monster.cpp:533
bool is_npc() const override
Definition: player.h:103

References _, Creature::add_effect(), monster::add_effect(), map::add_item(), add_msg(), monster::ammo, itype::bionic, bionic_manip_cos(), BIONIC_NOITEM_DIFFICULTY, bionics_uninstall_failure(), bionic_data::capacity, disp_name(), monster::disp_name(), effect_narcosis, effect_operating, effect_sleep, fault_bionic_nonsterile, item::faults, flag_BIONIC_FAULTY, g, get_map(), Creature::has_effect(), bionic_data::has_flag(), bionic::id, bionic::info(), player::is_npc(), player::is_player(), string_id< T >::is_valid(), bionic_data::itype(), itype_anesthetic, itype_burnt_out_bionic, m_bad, m_mixed, m_neutral, mod_max_power_level(), bionic_data::name, monster::name(), pos(), remove_bionic(), rng(), calendar::start_of_cataclysm, and behavior::success.

◆ uninstall_bionic() [2/2]

bool Character::uninstall_bionic ( const bionic_id b_id,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Initialize all the values needed to start the operation player_activity.

Definition at line 2055 of file bionics.cpp.

2057{
2058 // If malfunctioning bionics doesn't have associated item it gets predefined difficulty
2059 int difficulty = BIONIC_NOITEM_DIFFICULTY;
2060 if( b_id->itype().is_valid() ) {
2061 const itype *type = &*b_id->itype();
2062 if( type->bionic ) {
2063 difficulty = type->bionic->difficulty;
2064 }
2065 }
2066
2067 // removal of bionics adds +2 difficulty over installation
2068 float adjusted_skill;
2069 int pl_skill;
2070 if( autodoc ) {
2071 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
2074 skill_level );
2075 pl_skill = installer.bionics_pl_skill( skill_firstaid,
2078 skill_level );
2079 } else {
2080 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
2083 skill_level );
2084 pl_skill = installer.bionics_pl_skill( skill_electronics,
2087 skill_level );
2088 }
2089
2090 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty + 2 );
2091
2092 // Surgery is imminent, retract claws or blade if active
2093 for( bionic &bio : *installer.my_bionics ) {
2094 if( bio.powered && bio.info().has_flag( flag_BIONIC_WEAPON ) ) {
2095 installer.deactivate_bionic( bio );
2096 }
2097 }
2098
2099 int success = chance_of_success - rng( 1, 100 );
2100 if( installer.has_trait( trait_DEBUG_BIONICS ) ) {
2101 perform_uninstall( b_id, difficulty, success, b_id->capacity, pl_skill );
2102 return true;
2103 }
2104 assign_activity( ACT_OPERATION, to_moves<int>( difficulty * 20_minutes ) );
2105
2106 activity.values.push_back( difficulty );
2107 activity.values.push_back( success );
2108 activity.values.push_back( units::to_kilojoule( b_id->capacity ) );
2109 activity.values.push_back( pl_skill );
2110 activity.str_values.push_back( "uninstall" );
2111 activity.str_values.push_back( b_id.str() );
2112 activity.str_values.push_back( "" ); // installer_name is unused for uninstall
2113 if( autodoc ) {
2114 activity.str_values.push_back( "true" );
2115 } else {
2116 activity.str_values.push_back( "false" );
2117 }
2118 for( const std::pair<const bodypart_str_id, int> &elem : b_id->occupied_bodyparts ) {
2119 add_effect( effect_under_op, difficulty * 20_minutes, elem.first->token, difficulty );
2120 }
2121
2122 return true;
2123}
void perform_uninstall(bionic_id bid, int difficulty, int success, const units::energy &power_lvl, int pl_skill)
Succes or failure of removal happens here.
Definition: bionics.cpp:2125

References ACT_OPERATION, activity, Creature::add_effect(), assign_activity(), iexamine::autodoc(), bionic_manip_cos(), BIONIC_NOITEM_DIFFICULTY, bionics_adjusted_skill(), bionics_pl_skill(), bionic_data::capacity, deactivate_bionic(), effect_under_op, flag_BIONIC_WEAPON, bionic_data::has_flag(), has_trait(), bionic::info(), string_id< T >::is_valid(), bionic_data::itype(), my_bionics, bionic_data::occupied_bodyparts, perform_uninstall(), bionic::powered, rng(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, string_id< T >::str(), player_activity::str_values, behavior::success, units::to_kilojoule(), trait_DEBUG_BIONICS, type, and player_activity::values.

Referenced by iexamine::autodoc().

◆ unset_mutation()

void Character::unset_mutation ( const trait_id trait_)

Definition at line 165 of file mutation.cpp.

166{
167 // Take copy of argument because it might be a reference into a container
168 // we're about to erase from.
169 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
170 const trait_id trait = trait_;
171 const auto iter = my_mutations.find( trait );
172 if( iter == my_mutations.end() ) {
173 return;
174 }
175 my_mutations.erase( iter );
177 mutation_loss_effect( trait );
180}

References mutation_loss_effect(), my_mutations, rebuild_mutation_cache(), recalc_sight_limits(), and reset_encumbrance().

Referenced by clear_mutations(), wish_mutate_callback::key(), marloss_common(), mutate_towards(), iuse::mycus(), remove_mutation(), talk_effect_fun_t::set_remove_trait(), switch_mutations(), test_crossing_threshold(), toggle_trait(), and try_reject_mutagen().

◆ unwield()

bool Character::unwield ( )

Removes currently wielded item (if any)

Definition at line 3134 of file character.cpp.

3135{
3136 item &weapon = primary_weapon();
3137 if( weapon.is_null() ) {
3138 return true;
3139 }
3140
3141 if( !can_unwield( weapon ).success() ) {
3142 return false;
3143 }
3144
3145 const std::string query = string_format( _( "Stop wielding %s?" ), weapon.tname() );
3146
3147 if( !dispose_item( item_location( *this, &weapon ), query ) ) {
3148 return false;
3149 }
3150
3151 inv.unsort();
3152
3153 return true;
3154}

References _, can_unwield(), dispose_item(), inv, item::is_null(), primary_weapon(), string_format(), behavior::success, item::tname(), and inventory::unsort().

Referenced by character_funcs::try_wield_contents(), avatar::wield(), and avatar_action::wield().

◆ update_body() [1/2]

void Character::update_body ( )

Updates all "biology" by one turn.

Should be called once every turn.

Definition at line 4689 of file character.cpp.

4690{
4692}
void update_body()
Updates all "biology" by one turn.
Definition: character.cpp:4689

References calendar::turn, and update_body().

Referenced by game::do_turn(), npc::npc_update_body(), npc::on_load(), and update_body().

◆ update_body() [2/2]

void Character::update_body ( const time_point from,
const time_point to 
)

Updates all "biology" as if time between from and to passed.

Definition at line 4694 of file character.cpp.

4695{
4696 if( !is_npc() ) {
4697 update_stamina( to_turns<int>( to - from ) );
4698 }
4699 update_stomach( from, to );
4701 if( ticks_between( from, to, 3_minutes ) > 0 ) {
4702 magic->update_mana( *this->as_player(), to_turns<double>( 3_minutes ) );
4703 }
4704 const int five_mins = ticks_between( from, to, 5_minutes );
4705 if( five_mins > 0 ) {
4707 update_needs( five_mins );
4708 regen( five_mins );
4709 // Note: mend ticks once per 5 minutes, but wants rate in TURNS, not 5 minute intervals
4710 // TODO: change @ref med to take time_duration
4711 mend( five_mins * to_turns<int>( 5_minutes ) );
4712 }
4713 if( ticks_between( from, to, 24_hours ) > 0 ) {
4715 }
4716
4717 const int thirty_mins = ticks_between( from, to, 30_minutes );
4718 if( thirty_mins > 0 ) {
4719 // Radiation kills health even at low doses
4721 }
4722
4723 for( const auto &v : vitamin::all() ) {
4724 const time_duration rate = vitamin_rate( v.first );
4725 if( rate > 0_turns ) {
4726 int qty = ticks_between( from, to, rate );
4727 if( qty > 0 ) {
4728 vitamin_mod( v.first, 0 - qty );
4729 }
4730
4731 } else if( rate < 0_turns ) {
4732 // mutations can result in vitamins being generated (but never accumulated)
4733 int qty = ticks_between( from, to, -rate );
4734 if( qty > 0 ) {
4735 vitamin_mod( v.first, qty );
4736 }
4737 }
4738 }
4739
4740 do_skill_rust();
4741}
int ticks_between(const time_point &from, const time_point &to, const time_duration &tick_length)
Definition: character.cpp:4682
static const trait_id trait_RADIOGENIC("RADIOGENIC")
void check_needs_extremes()
Kills the player if too hungry, stimmed up etc., forces tired player to sleep and prints warnings.
Definition: character.cpp:4996
void do_skill_rust()
Definition: character.cpp:3599
void update_needs(int rate_multiplier)
Increases hunger, thirst, fatigue and stimulants wearing off.
Definition: character.cpp:4800
virtual void update_health(int external_modifiers=0)
Handles health fluctuations over time.
Definition: character.cpp:4645
void regen(int rate_multiplier)
Handles passive regeneration of pain and maybe hp.
Definition: character.cpp:4572
void update_stomach(const time_point &from, const time_point &to)
Updates the stomach to give accurate hunger messages.
Definition: character.cpp:4757
void mend(int rate_multiplier)
Handles the chance for broken limbs to spontaneously heal to 1 HP.
Definition: suffer.cpp:1672
time_duration vitamin_rate(const vitamin_id &vit) const
Get vitamin usage rate (minutes per unit) accounting for bionics, mutations and effects.
void enforce_minimum_healing()
Definition: character.cpp:4635
void update_stamina(int turns)
Regenerates stamina.
Definition: character.cpp:7166

References vitamin::all(), Creature::as_player(), check_needs_extremes(), do_skill_rust(), enforce_minimum_healing(), get_rad(), has_trait(), Creature::is_npc(), magic, mend(), recalculate_enchantment_cache(), regen(), ticks_between(), trait_RADIOGENIC, update_health(), update_needs(), update_stamina(), update_stomach(), vitamin_mod(), and vitamin_rate().

◆ update_bodytemp()

void Character::update_bodytemp ( const map m,
const weather_manager weather 
)

Maintains body temperature.

Calculations that affect all body parts equally go here, not in the loop

Source : http://www.atc.army.mil/weather/windchill.pdf

Temperature and wind chill are main factors, mitigated by clothing warmth. Each 10 warmth protects against 2C of cold.

1200 turns in low risk, + 3 tics 450 turns in moderate risk, + 8 tics 50 turns in high risk, +72 tics

Let's say frostnip @ 1800 tics, frostbite @ 3600 tics

Chunked into 8 parts (http://imgur.com/xlTPmJF)

– 2 hour risk – Between 30F and 10F Between 10F and -5F, less than 20mph, -4x + 3y - 20 > 0, x : F, y : mph – 45 minute risk – Between 10F and -5F, less than 20mph, -4x + 3y - 20 < 0, x : F, y : mph Between 10F and -5F, greater than 20mph Less than -5F, less than 10 mph Less than -5F, more than 10 mph, -4x + 3y - 170 > 0, x : F, y : mph – 5 minute risk – Less than -5F, more than 10 mph, -4x + 3y - 170 < 0, x : F, y : mph Less than -35F, more than 10 mp

Definition at line 5215 of file character.cpp.

5216{
5217 if( has_trait( trait_DEBUG_NOTEMP ) ) {
5218 temp_cur.fill( BODYTEMP_NORM );
5219 temp_conv.fill( BODYTEMP_NORM );
5220 return;
5221 }
5222 /* Cache calls to g->get_temperature( player position ), used in several places in function */
5223 const auto player_local_temp = weather.get_temperature( pos() );
5224 // NOTE : visit weather.h for some details on the numbers used
5225 // In Celsius / 100
5226 int Ctemperature = static_cast<int>( 100 * units::fahrenheit_to_celsius( player_local_temp ) );
5227 const w_point &weather_point = get_weather().get_precise();
5228 int vehwindspeed = 0;
5229 const optional_vpart_position vp = m.veh_at( pos() );
5230 if( vp ) {
5231 vehwindspeed = std::abs( vp->vehicle().velocity / 100 ); // vehicle velocity in mph
5232 }
5233 const oter_id &cur_om_ter = overmap_buffer.ter( global_omt_location() );
5234 bool sheltered = weather::is_sheltered( m, pos() );
5235 double total_windpower = get_local_windpower( weather.windspeed + vehwindspeed, cur_om_ter,
5236 pos(),
5237 weather.winddirection, sheltered );
5238 int air_humidity = get_local_humidity( weather_point.humidity, weather.weather_id,
5239 sheltered );
5240 // Let's cache this not to check it num_bp times
5241 const bool has_bark = has_trait( trait_BARK );
5242 const bool has_heatsink = has_bionic( bio_heatsink ) || is_wearing( itype_rm13_armor_on ) ||
5244 const bool has_climate_control = in_climate_control();
5245 const bool use_floor_warmth = can_use_floor_warmth();
5246 // In bodytemp units
5247 const int ambient_norm = 1900 - BODYTEMP_NORM;
5248
5249 /**
5250 * Calculations that affect all body parts equally go here, not in the loop
5251 */
5252 const int sunlight_warmth = weather::is_in_sunlight( m, pos(), weather.weather_id )
5253 ? ( weather.weather_id->sun_intensity == sun_intensity_type::high ? 1000 : 500 )
5254 : 0;
5255 const int best_fire = get_heat_radiation( pos(), true );
5256 const bool pyromania = has_trait( trait_PYROMANIA );
5257
5258 const int lying_warmth = use_floor_warmth ? floor_warmth( pos() ) : 0;
5259 const int water_temperature_raw =
5260 100 * units::fahrenheit_to_celsius( weather.get_water_temperature( pos() ) );
5261 // Rescale so that 0C is 0 (FREEZING) and 30C is 5k (NORM).
5262 const int water_temperature = water_temperature_raw * 5 / 3;
5263
5264 // Correction of body temperature due to traits and mutations
5265 // Lower heat is applied always
5266 const int mutation_heat_low = bodytemp_modifier_traits( true );
5267 const int mutation_heat_high = bodytemp_modifier_traits( false );
5268 // Difference between high and low is the "safe" heat - one we only apply if it's beneficial
5269 const int mutation_heat_bonus = mutation_heat_high - mutation_heat_low;
5270
5271 // Note: this is included in @ref weather::get_temperature(), so don't add to bodytemp!
5272 const int h_radiation = get_heat_radiation( pos(), false );
5273
5274 // If you're standing in water, air temperature is replaced by water temperature. No wind.
5275 const ter_id ter_at_pos = m.ter( pos() );
5276 const bool submerged = !in_vehicle && ter_at_pos->has_flag( TFLAG_DEEP_WATER );
5277 const bool submerged_low = !in_vehicle && ( submerged || ter_at_pos->has_flag( TFLAG_SWIMMABLE ) );
5278
5279 std::map<bodypart_id, std::vector<const item *>> clothing_map;
5280 std::map<bodypart_id, std::vector<const item *>> bonus_clothing_map;
5281 for( const bodypart_id &bp : get_all_body_parts() ) {
5282 clothing_map.emplace( bp, std::vector<const item *>() );
5283 bonus_clothing_map.emplace( bp, std::vector<const item *>() );
5284 // HACK: we're using temp_conv here to temporarily save
5285 // temperature values from before equalization.
5286 temp_conv[bp->token] = temp_cur[bp->token];
5287 }
5288
5289 // EQUALIZATION
5290 // We run it outside the loop because we can and so we should
5291 // Also, it makes bonus heat application more stable
5292 // TODO: Affect future convection temperature instead (might require adding back to loop)
5298
5301
5304
5305 for( const item &it : worn ) {
5306 // TODO: Port body part set id changes
5307 const body_part_set &covered = it.get_covered_body_parts();
5308 for( size_t i = 0; i < num_bp; i++ ) {
5309 body_part token = static_cast<body_part>( i );
5310 if( covered.test( token ) ) {
5311 clothing_map[convert_bp( token )].emplace_back( &it );
5312 }
5313 if( it.has_flag( flag_HOOD ) ) {
5314 bonus_clothing_map[body_part_head].emplace_back( &it );
5315 }
5316 if( it.has_flag( flag_COLLAR ) ) {
5317 bonus_clothing_map[body_part_mouth].emplace_back( &it );
5318 }
5319 if( it.has_flag( flag_POCKETS ) ) {
5320 bonus_clothing_map[body_part_hand_l].emplace_back( &it );
5321 bonus_clothing_map[body_part_hand_r].emplace_back( &it );
5322 }
5323 }
5324 }
5325 // If player is wielding something large, pockets are not usable
5326 const item &weapon = primary_weapon();
5327 if( weapon.volume() >= 500_ml ) {
5328 bonus_clothing_map[body_part_hand_l].clear();
5329 bonus_clothing_map[body_part_hand_r].clear();
5330 }
5331 // If player's head is encumbered, hood can't be put up
5332 if( encumb( body_part_head->token ) >= 10 ) {
5333 bonus_clothing_map[body_part_head].clear();
5334 }
5335 // Similar for mouth
5336 if( encumb( body_part_mouth->token ) >= 10 ) {
5337 bonus_clothing_map[body_part_mouth].clear();
5338 }
5339
5340 std::map<bodypart_id, int> warmth_per_bp = warmth::from_clothing( clothing_map );
5341 std::map<bodypart_id, int> bonus_warmth_per_bp = warmth::bonus_from_clothing( bonus_clothing_map );
5342 for( const auto &pr : warmth::from_effects( *this ) ) {
5343 warmth_per_bp[pr.first] += pr.second;
5344 }
5345
5346 std::map<bodypart_id, int> wind_res_per_bp = warmth::wind_resistance_from_clothing( clothing_map );
5347 std::map<bodypart_id, int> wind_res_per_bp_bonus = warmth::wind_resistance_from_clothing(
5348 bonus_clothing_map );
5349 for( std::pair<const bodypart_id, int> &bp_wind_res : wind_res_per_bp ) {
5350 int exposed = std::max( 0, 100 - bp_wind_res.second );
5351 int exposed_bonus = std::max( 0, 100 - wind_res_per_bp_bonus.at( bp_wind_res.first ) );
5352 int exposed_final = exposed * exposed_bonus / ( 100 * 100 );
5353 bp_wind_res.second = 100 - exposed_final;
5354 }
5356 for( std::pair<const bodypart_id, int> &bp_wind_res : wind_res_per_bp ) {
5357 bp_wind_res.second = 100;
5358 }
5359 }
5360 // We might not use this at all, so leave it empty
5361 // If we do need to use it, we'll initialize it (once) there
5362 std::map<bodypart_id, int> fire_armor_per_bp;
5363
5364 // Current temperature and converging temperature calculations
5365 for( const bodypart_id &bp : get_all_body_parts() ) {
5366 // Skip eyes
5367 if( bp == bodypart_id( "eyes" ) ) {
5368 continue;
5369 }
5370
5371 const bool submerged_bp = submerged ||
5372 ( submerged_low &&
5373 ( bp == body_part_foot_l ||
5374 bp == body_part_foot_r ||
5375 bp == body_part_leg_l ||
5376 bp == body_part_leg_r ) );
5377 // This adjusts the temperature scale to match the bodytemp scale
5378 const int adjusted_temp = submerged_bp ?
5379 water_temperature :
5380 ( Ctemperature - ambient_norm );
5381
5382 // Represents the fact that the body generates heat when it is cold.
5383 double scaled_temperature = logarithmic_range( BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT,
5384 temp_cur[bp->token] );
5385 // Produces a smooth curve between 30.0 and 60.0.
5386 double homeostasis_adjustment = 30.0 * ( 1.0 + scaled_temperature );
5387 int clothing_warmth_adjustment = static_cast<int>( homeostasis_adjustment * warmth_per_bp[bp] );
5388 int clothing_warmth_adjusted_bonus = static_cast<int>( homeostasis_adjustment *
5389 bonus_warmth_per_bp[bp] );
5390 // WINDCHILL
5391 double bp_windpower = total_windpower * ( 1 - wind_res_per_bp[bp] / 100.0 );
5392 // Calculate windchill
5393 int windchill = submerged_bp
5394 ? 0
5395 : get_local_windchill( player_local_temp,
5396 air_humidity,
5397 bp_windpower );
5398
5399 // Convergent temperature is affected by ambient temperature,
5400 // clothing warmth, and body wetness.
5401 int bp_conv = adjusted_temp
5402 + windchill * 100
5403 + clothing_warmth_adjustment
5404 + mutation_heat_low
5405 + sunlight_warmth;
5406
5407 // Bark : lowers blister count to -5; harder to get blisters
5408 // If the counter is high, your skin starts to burn
5409 int blister_count = ( has_bark ? -5 : 0 );
5410
5411 if( frostbite_timer[bp->token] > 0 ) {
5412 frostbite_timer[bp->token] -= std::min( 5, h_radiation );
5413 }
5414 blister_count += h_radiation - 111 > 0 ?
5415 std::max( static_cast<int>( std::sqrt( h_radiation - 111 ) ), 0 ) : 0;
5416
5417 if( has_heatsink ) {
5418 blister_count -= 20;
5419 }
5420 if( fire_armor_per_bp.empty() && blister_count > 0 ) {
5421 fire_armor_per_bp = get_armor_fire( clothing_map );
5422 }
5423 // BLISTERS : Skin gets blisters from intense heat exposure.
5424 // Fire protection protects from blisters.
5425 // Heatsinks give near-immunity.
5426 if( blister_count - fire_armor_per_bp[bp] > 0 ) {
5427 add_effect( effect_blisters, 1_turns, bp->token );
5428 if( pyromania ) {
5429 add_morale( MORALE_PYROMANIA_NEARFIRE, 10, 10, 1_hours,
5430 30_minutes ); // Proximity that's close enough to harm us gives us a bit of a thrill
5432 }
5433 } else if( pyromania && best_fire >= 1 ) { // Only give us fire bonus if there's actually fire
5434 add_morale( MORALE_PYROMANIA_NEARFIRE, 5, 5, 30_minutes,
5435 15_minutes ); // Gain a much smaller mood boost even if it doesn't hurt us
5437 }
5438
5439 // Climate Control eases the effects of high and low ambient temps
5440 if( has_climate_control ) {
5441 bp_conv = temp_corrected_by_climate_control( bp_conv );
5442 }
5443
5444 int bonus_fire_warmth = best_fire * 500;
5445
5446 const int comfortable_warmth = bonus_fire_warmth + lying_warmth;
5447 const int bonus_warmth = comfortable_warmth + mutation_heat_bonus + clothing_warmth_adjusted_bonus;
5448 if( bonus_warmth > 0 ) {
5449 // Approximate bp_conv needed to reach comfortable temperature in this very turn
5450 // Basically inverted formula for temp_cur below
5451 int desired = 501 * BODYTEMP_NORM - 499 * temp_cur[bp->token];
5452 if( std::abs( BODYTEMP_NORM - desired ) < 1000 ) {
5453 desired = BODYTEMP_NORM; // Ensure that it converges
5454 } else if( desired > BODYTEMP_HOT ) {
5455 desired = BODYTEMP_HOT; // Cap excess at sane temperature
5456 }
5457
5458 if( desired < bp_conv ) {
5459 // Too hot, can't help here
5460 } else if( desired < bp_conv + bonus_warmth ) {
5461 // Use some heat, but not all of it
5462 bp_conv = desired;
5463 } else {
5464 // Use all the heat
5465 bp_conv += bonus_warmth;
5466 }
5467
5468 // Morale bonus for comfiness - only if actually comfy (not too warm/cold)
5469 // Spread the morale bonus in time.
5470 if( comfortable_warmth > 0 &&
5471 // TODO: make this simpler and use time_duration/time_point
5472 to_turn<int>( calendar::turn ) % to_turns<int>( 1_minutes ) == to_turns<int>
5473 ( 1_minutes * bp->token ) / to_turns<int>( 1_minutes * num_bp ) &&
5475 get_effect_int( effect_hot, num_bp ) == 0 &&
5476 temp_cur[bp->token] > BODYTEMP_COLD && temp_cur[bp->token] <= BODYTEMP_NORM ) {
5477 add_morale( MORALE_COMFY, 1, 10, 2_minutes, 1_minutes, true );
5478 }
5479 }
5480
5481 // The current temperature model can't account for water temperature conduction well
5482 // Hack: cut non-water effects by 80% when in water
5483 if( submerged_bp ) {
5484 bp_conv = ( ( bp_conv - adjusted_temp ) / 5 ) + adjusted_temp;
5485 }
5486
5487 // FINAL CALCULATION : Increments current body temperature towards convergent.
5488 int temp_before = temp_cur[bp->token];
5489 int temp_difference = temp_before - bp_conv; // Negative if the player is warming up.
5490 int rounding_error = 0;
5491 // If temp_diff is small, the player cannot warm up due to rounding errors. This fixes that.
5492 if( temp_difference < 0 && temp_difference > -600 ) {
5493 rounding_error = 1;
5494 }
5495 // exp(-0.001) : half life of 60 minutes, exp(-0.002) : half life of 30 minutes,
5496 // exp(-0.003) : half life of 20 minutes, exp(-0.004) : half life of 15 minutes
5497 static const double change_mult_air = std::exp( -0.002 );
5498 static const double change_mult_water = std::exp( -0.008 );
5499 const double change_mult = submerged_bp ? change_mult_water : change_mult_air;
5500 if( temp_cur[bp->token] != bp_conv ) {
5501 temp_cur[bp->token] = static_cast<int>( temp_difference * change_mult )
5502 + bp_conv + rounding_error;
5503 }
5504 int temp_after = temp_cur[bp->token];
5505 // PENALTIES
5506 if( temp_cur[bp->token] < BODYTEMP_FREEZING ) {
5507 add_effect( effect_cold, 1_turns, bp->token, 3 );
5508 } else if( temp_cur[bp->token] < BODYTEMP_VERY_COLD ) {
5509 add_effect( effect_cold, 1_turns, bp->token, 2 );
5510 } else if( temp_cur[bp->token] < BODYTEMP_COLD ) {
5511 add_effect( effect_cold, 1_turns, bp->token, 1 );
5512 } else if( temp_cur[bp->token] > BODYTEMP_SCORCHING ) {
5513 add_effect( effect_hot, 1_turns, bp->token, 3 );
5514 if( bp->main_part.id() == bp ) {
5515 add_effect( effect_hot_speed, 1_turns, bp->token, 3 );
5516 }
5517 } else if( temp_cur[bp->token] > BODYTEMP_VERY_HOT ) {
5518 add_effect( effect_hot, 1_turns, bp->token, 2 );
5519 if( bp->main_part.id() == bp ) {
5520 add_effect( effect_hot_speed, 1_turns, bp->token, 2 );
5521 }
5522 } else if( temp_cur[bp->token] > BODYTEMP_HOT ) {
5523 add_effect( effect_hot, 1_turns, bp->token, 1 );
5524 if( bp->main_part.id() == bp ) {
5525 add_effect( effect_hot_speed, 1_turns, bp->token, 1 );
5526 }
5527 } else {
5528 if( temp_cur[bp->token] >= BODYTEMP_COLD ) {
5529 remove_effect( effect_cold, bp->token );
5530 }
5531 if( temp_cur[bp->token] <= BODYTEMP_HOT ) {
5532 remove_effect( effect_hot, bp->token );
5533 remove_effect( effect_hot_speed, bp->token );
5534 }
5535 }
5536
5537 // FROSTBITE - only occurs to hands, feet, face
5538 /**
5539
5540 Source : http://www.atc.army.mil/weather/windchill.pdf
5541
5542 Temperature and wind chill are main factors, mitigated by clothing warmth. Each 10 warmth protects against 2C of cold.
5543
5544 1200 turns in low risk, + 3 tics
5545 450 turns in moderate risk, + 8 tics
5546 50 turns in high risk, +72 tics
5547
5548 Let's say frostnip @ 1800 tics, frostbite @ 3600 tics
5549
5550 >> Chunked into 8 parts (http://imgur.com/xlTPmJF)
5551 -- 2 hour risk --
5552 Between 30F and 10F
5553 Between 10F and -5F, less than 20mph, -4x + 3y - 20 > 0, x : F, y : mph
5554 -- 45 minute risk --
5555 Between 10F and -5F, less than 20mph, -4x + 3y - 20 < 0, x : F, y : mph
5556 Between 10F and -5F, greater than 20mph
5557 Less than -5F, less than 10 mph
5558 Less than -5F, more than 10 mph, -4x + 3y - 170 > 0, x : F, y : mph
5559 -- 5 minute risk --
5560 Less than -5F, more than 10 mph, -4x + 3y - 170 < 0, x : F, y : mph
5561 Less than -35F, more than 10 mp
5562 **/
5563
5564 if( bp == body_part_mouth || bp == body_part_foot_r ||
5565 bp == body_part_foot_l || bp == body_part_hand_r || bp == body_part_hand_l ) {
5566 // Handle the frostbite timer
5567 // Need temps in F, windPower already in mph
5568 int wetness_percentage = 100 * body_wetness[bp->token] / drench_capacity[bp->token]; // 0 - 100
5569 // Warmth gives a slight buff to temperature resistance
5570 // Wetness gives a heavy nerf to temperature resistance
5571 double adjusted_warmth = warmth_per_bp.at( bp ) - wetness_percentage;
5572 int Ftemperature = static_cast<int>( player_local_temp + 0.2 * adjusted_warmth );
5573 // Windchill reduced by your armor
5574 int FBwindPower = static_cast<int>(
5575 total_windpower * ( 1 - wind_res_per_bp[ bp ] / 100.0 ) );
5576
5577 int intense = get_effect_int( effect_frostbite, bp->token );
5578
5579 // This has been broken down into 8 zones
5580 // Low risk zones (stops at frostnip)
5581 if( temp_cur[bp->token] < BODYTEMP_COLD &&
5582 ( ( Ftemperature < 30 && Ftemperature >= 10 ) ||
5583 ( Ftemperature < 10 && Ftemperature >= -5 &&
5584 FBwindPower < 20 && -4 * Ftemperature + 3 * FBwindPower - 20 >= 0 ) ) ) {
5585 if( frostbite_timer[bp->token] < 2000 ) {
5586 frostbite_timer[bp->token] += 3;
5587 }
5588 if( one_in( 100 ) && !has_effect( effect_frostbite, bp->token ) ) {
5589 add_msg( m_warning, _( "Your %s will be frostnipped in the next few hours." ),
5590 body_part_name( bp->token ) );
5591 }
5592 // Medium risk zones
5593 } else if( temp_cur[bp->token] < BODYTEMP_COLD &&
5594 ( ( Ftemperature < 10 && Ftemperature >= -5 && FBwindPower < 20 &&
5595 -4 * Ftemperature + 3 * FBwindPower - 20 < 0 ) ||
5596 ( Ftemperature < 10 && Ftemperature >= -5 && FBwindPower >= 20 ) ||
5597 ( Ftemperature < -5 && FBwindPower < 10 ) ||
5598 ( Ftemperature < -5 && FBwindPower >= 10 &&
5599 -4 * Ftemperature + 3 * FBwindPower - 170 >= 0 ) ) ) {
5600 frostbite_timer[bp->token] += 8;
5601 if( one_in( 100 ) && intense < 2 ) {
5602 add_msg( m_warning, _( "Your %s will be frostbitten within the hour!" ),
5603 body_part_name( bp->token ) );
5604 }
5605 // High risk zones
5606 } else if( temp_cur[bp->token] < BODYTEMP_COLD &&
5607 ( ( Ftemperature < -5 && FBwindPower >= 10 &&
5608 -4 * Ftemperature + 3 * FBwindPower - 170 < 0 ) ||
5609 ( Ftemperature < -35 && FBwindPower >= 10 ) ) ) {
5610 frostbite_timer[bp->token] += 72;
5611 if( one_in( 100 ) && intense < 2 ) {
5612 add_msg( m_warning, _( "Your %s will be frostbitten any minute now!" ),
5613 body_part_name( bp->token ) );
5614 }
5615 // Risk free, so reduce frostbite timer
5616 } else {
5617 frostbite_timer[bp->token] -= 3;
5618 }
5619
5620 // Handle the bestowing of frostbite
5621 if( frostbite_timer[bp->token] < 0 ) {
5622 frostbite_timer[bp->token] = 0;
5623 } else if( frostbite_timer[bp->token] > 4200 ) {
5624 // This ensures that the player will recover in at most 3 hours.
5625 frostbite_timer[bp->token] = 4200;
5626 }
5627 // Frostbite, no recovery possible
5628 if( frostbite_timer[bp->token] >= 3600 ) {
5629 add_effect( effect_frostbite, 1_turns, bp->token, 2 );
5631 // Else frostnip, add recovery if we were frostbitten
5632 } else if( frostbite_timer[bp->token] >= 1800 ) {
5633 if( intense == 2 ) {
5634 add_effect( effect_frostbite_recovery, 1_turns, bp->token );
5635 }
5636 add_effect( effect_frostbite, 1_turns, bp->token, 1 );
5637 // Else fully recovered
5638 } else if( frostbite_timer[bp->token] == 0 ) {
5639 remove_effect( effect_frostbite, bp->token );
5641 }
5642 }
5643 // Warn the player if condition worsens
5644 // HACK: we want overall temperature change, including equalization, and temp_conv
5645 // at this moment contains temperature values from before the equalization.
5646 temp_before = temp_conv[bp->token];
5647 if( temp_before > BODYTEMP_FREEZING && temp_after <= BODYTEMP_FREEZING ) {
5648 //~ %s is bodypart
5649 add_msg( m_warning, _( "You feel your %s beginning to go numb from the cold!" ),
5650 body_part_name( bp->token ) );
5651 } else if( temp_before > BODYTEMP_VERY_COLD && temp_after <= BODYTEMP_VERY_COLD ) {
5652 //~ %s is bodypart
5653 add_msg( m_warning, _( "You feel your %s getting very cold." ),
5654 body_part_name( bp->token ) );
5655 } else if( temp_before > BODYTEMP_COLD && temp_after <= BODYTEMP_COLD ) {
5656 //~ %s is bodypart
5657 add_msg( m_warning, _( "You feel your %s getting chilly." ),
5658 body_part_name( bp->token ) );
5659 } else if( temp_before < BODYTEMP_SCORCHING && temp_after >= BODYTEMP_SCORCHING ) {
5660 //~ %s is bodypart
5661 add_msg( m_bad, _( "You feel your %s getting red hot from the heat!" ),
5662 body_part_name( bp->token ) );
5663 } else if( temp_before < BODYTEMP_VERY_HOT && temp_after >= BODYTEMP_VERY_HOT ) {
5664 //~ %s is bodypart
5665 add_msg( m_warning, _( "You feel your %s getting very hot." ),
5666 body_part_name( bp->token ) );
5667 } else if( temp_before < BODYTEMP_HOT && temp_after >= BODYTEMP_HOT ) {
5668 //~ %s is bodypart
5669 add_msg( m_warning, _( "You feel your %s getting warm." ),
5670 body_part_name( bp->token ) );
5671 }
5672
5673 // Note: Numbers are based off of BODYTEMP at the top of weather.h
5674 // If torso is BODYTEMP_COLD which is 34C, the early stages of hypothermia begin
5675 // constant shivering will prevent the player from falling asleep.
5676 // Otherwise, if any other body part is BODYTEMP_VERY_COLD, or 31C
5677 // AND you have frostbite, then that also prevents you from sleeping
5678 if( in_sleep_state() ) {
5679 int curr_temperature = temp_cur[bp->token];
5680 if( bp == body_part_torso && curr_temperature <= BODYTEMP_COLD ) {
5681 add_msg( m_warning, _( "Your shivering prevents you from sleeping." ) );
5682 wake_up();
5683 } else if( bp != body_part_torso && curr_temperature <= BODYTEMP_VERY_COLD &&
5685 add_msg( m_warning, _( "You are too cold. Your frostbite prevents you from sleeping." ) );
5686 wake_up();
5687 }
5688 }
5689
5690 // Warn the player that wind is going to be a problem.
5691 // But only if it can be a problem, no need to spam player with "wind chills your scorching body"
5692 if( bp_conv <= BODYTEMP_COLD && windchill < -10 && one_in( 200 ) ) {
5693 add_msg( m_bad, _( "The wind is making your %s feel quite cold." ),
5694 body_part_name( bp->token ) );
5695 } else if( bp_conv <= BODYTEMP_COLD && windchill < -20 && one_in( 100 ) ) {
5696 add_msg( m_bad,
5697 _( "The wind is very strong, you should find some more wind-resistant clothing for your %s." ),
5698 body_part_name( bp->token ) );
5699 } else if( bp_conv <= BODYTEMP_COLD && windchill < -30 && one_in( 50 ) ) {
5700 add_msg( m_bad, _( "Your clothing is not providing enough protection from the wind for your %s!" ),
5701 body_part_name( bp->token ) );
5702 }
5703
5704 // Set temp_conv just once per bp for readability
5705 // TODO: Remove temp_conv, it's only really for display, so should not be in Character
5706 temp_conv[bp->token] = bp_conv;
5707 }
5708}
const bodypart_str_id body_part_foot_r("foot_r")
const bodypart_str_id body_part_hand_r("hand_r")
const bodypart_str_id body_part_leg_l("leg_l")
const bodypart_str_id body_part_arm_l("arm_l")
const bodypart_str_id body_part_torso("torso")
const bodypart_str_id body_part_leg_r("leg_r")
const bodypart_str_id body_part_mouth("mouth")
const bodypart_str_id body_part_head("head")
const bodypart_str_id body_part_hand_l("hand_l")
const bodypart_str_id body_part_foot_l("foot_l")
static const efftype_id effect_cold("cold")
static const trait_id trait_DEBUG_NOTEMP("DEBUG_NOTEMP")
static const trait_id trait_BARK("BARK")
static const flag_str_id flag_POCKETS("POCKETS")
static const efftype_id effect_hot("hot")
static const flag_str_id flag_HOOD("HOOD")
static const trait_id trait_PYROMANIA("PYROMANIA")
static const efftype_id effect_blisters("blisters")
static const efftype_id effect_frostbite_recovery("frostbite_recovery")
static const efftype_id effect_hot_speed("hot_speed")
static const flag_str_id flag_COLLAR("COLLAR")
static const efftype_id effect_frostbite("frostbite")
int temp_corrected_by_climate_control(int temperature) const
Value of the body temperature corrected by climate control.
Definition: character.cpp:9564
std::map< bodypart_id, int > get_armor_fire(const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
Returns overall fire resistance.
Definition: character.cpp:8250
bool can_use_floor_warmth() const
Can the player lie down and cover self with blankets etc.
Definition: character.cpp:9442
int bodytemp_modifier_traits(bool overheated) const
Correction factor of the body temperature due to traits and mutations.
Definition: character.cpp:9546
bool in_climate_control()
Returns true if the player is in a climate controlled area or armor.
Definition: character.cpp:3852
void temp_equalizer(const bodypart_id &bp1, const bodypart_id &bp2)
Equalizes heat between body parts.
Definition: character.cpp:5710
int floor_warmth(const tripoint &pos) const
Final warmth from the floor.
Definition: character.cpp:9531
int get_heat_radiation(const tripoint &location, bool direct)
Definition: game.cpp:1797
const morale_type MORALE_COMFY("morale_comfy")
constexpr double fahrenheit_to_celsius(double fahrenheit)
std::map< bodypart_id, int > bonus_from_clothing(const std::map< bodypart_id, std::vector< const item * > > &clothing_map)
Definition: character.cpp:9425
std::map< bodypart_id, int > wind_resistance_from_clothing(const std::map< bodypart_id, std::vector< const item * > > &clothing_map)
Returns wind resistance provided by armor, etc.
Definition: character.cpp:3908
std::map< bodypart_id, int > from_effects(const Character &c)
Definition: character.cpp:9431
std::map< bodypart_id, int > from_clothing(const std::map< bodypart_id, std::vector< const item * > > &clothing_map)
Definition: character.cpp:9419
bool is_in_sunlight(const map &m, const tripoint &p, const weather_type_id &weather)
Definition: weather.cpp:1162
bool is_sheltered(const map &m, const tripoint &p)
Definition: weather.cpp:1153
bool has_flag(const std::string &flag) const
Definition: mapdata.h:419

References _, Creature::add_effect(), add_morale(), add_msg(), bio_heatsink, body_part_arm_l, body_part_arm_r, body_part_foot_l, body_part_foot_r, body_part_hand_l, body_part_hand_r, body_part_head, body_part_leg_l, body_part_leg_r, body_part_mouth, body_part_name(), body_part_torso, body_wetness, BODYTEMP_COLD, BODYTEMP_FREEZING, BODYTEMP_HOT, bodytemp_modifier_traits(), BODYTEMP_NORM, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, warmth::bonus_from_clothing(), can_use_floor_warmth(), convert_bp(), drench_capacity, effect_blisters, effect_cold, effect_frostbite, effect_frostbite_recovery, effect_hot, effect_hot_speed, encumb(), units::fahrenheit_to_celsius(), flag_COLLAR, flag_HOOD, flag_POCKETS, floor_warmth(), warmth::from_clothing(), warmth::from_effects(), frostbite_timer, Creature::get_all_body_parts(), get_armor_fire(), Creature::get_effect_int(), get_heat_radiation(), get_local_humidity(), get_local_windchill(), get_local_windpower(), weather_manager::get_precise(), get_weather(), global_omt_location(), has_active_mutation(), has_bionic(), Creature::has_effect(), map_data_common_t::has_flag(), has_trait(), high, w_point::humidity, in_climate_control(), in_sleep_state(), in_vehicle, weather::is_in_sunlight(), weather::is_sheltered(), is_wearing(), itype_rm13_armor_on, logarithmic_range(), m_bad, m_warning, MORALE_COMFY, MORALE_PYROMANIA_NEARFIRE, MORALE_PYROMANIA_NOFIRE, num_bp, one_in(), overmap_buffer, pos(), primary_weapon(), rem_morale(), Creature::remove_effect(), temp_conv, temp_corrected_by_climate_control(), temp_cur, temp_equalizer(), map::ter(), overmapbuffer::ter(), body_part_set::test(), TFLAG_DEEP_WATER, TFLAG_SWIMMABLE, body_part_type::token, trait_BARK, trait_DEBUG_NOTEMP, trait_M_SKIN2, trait_M_SKIN3, trait_PYROMANIA, trait_SHELL2, calendar::turn, map::veh_at(), item::volume(), wake_up(), warmth::wind_resistance_from_clothing(), and worn.

Referenced by game::do_turn(), and iuse_transform::use().

◆ update_fuel_storage()

void Character::update_fuel_storage ( const itype_id fuel)

Updates which bionic contain fuel and which is empty.

Definition at line 2068 of file character.cpp.

2069{
2070 const item it( fuel );
2071 if( get_value( fuel.str() ).empty() ) {
2072 for( const bionic_id &bid : get_bionic_fueled_with( it ) ) {
2073 remove_value( bid.c_str() );
2074 }
2075 return;
2076 }
2077
2078 std::vector<bionic_id> bids = get_bionic_fueled_with( it );
2079 if( bids.empty() ) {
2080 return;
2081 }
2082 int amount_fuel_loaded = std::stoi( get_value( fuel.str() ) );
2083 std::vector<bionic_id> loaded_bio;
2084
2085 // Sort bionic in order of decreasing capacity
2086 // To fill the bigger ones firts.
2087 bool swap = true;
2088 while( swap ) {
2089 swap = false;
2090 for( size_t i = 0; i < bids.size() - 1; i++ ) {
2091 if( bids[i + 1]->fuel_capacity > bids[i]->fuel_capacity ) {
2092 std::swap( bids[i + 1], bids[i] );
2093 swap = true;
2094 }
2095 }
2096 }
2097
2098 for( const bionic_id &bid : bids ) {
2099 remove_value( bid.c_str() );
2100 if( bid->fuel_capacity <= amount_fuel_loaded ) {
2101 amount_fuel_loaded -= bid->fuel_capacity;
2102 loaded_bio.emplace_back( bid );
2103 } else if( amount_fuel_loaded != 0 ) {
2104 loaded_bio.emplace_back( bid );
2105 break;
2106 }
2107 }
2108
2109 for( const bionic_id &bd : loaded_bio ) {
2110 set_value( bd.str(), fuel.str() );
2111 }
2112
2113}
void swap(colony< element_type, element_allocator_type, element_skipfield_type > &a, colony< element_type, element_allocator_type, element_skipfield_type > &b) COLONY_NOEXCEPT_SWAP(element_allocator_type)
Swaps colony A's contents with that of colony B.
Definition: colony.h:3496

References get_bionic_fueled_with(), Creature::get_value(), Creature::remove_value(), Creature::set_value(), string_id< T >::str(), and cata::swap().

Referenced by burn_fuel(), fuel_bionic_with(), and suffer_from_radiation().

◆ update_health()

void Character::update_health ( int  external_modifiers = 0)
virtual

Handles health fluctuations over time.

Definition at line 4645 of file character.cpp.

4646{
4647 if( has_artifact_with( AEP_SICK ) ) {
4648 // Carrying a sickness artifact makes your health 50 points worse on average
4649 external_modifiers -= 50;
4650 }
4651 // Limit healthy_mod to [-200, 200].
4652 // This also sets approximate bounds for the character's health.
4653 if( get_healthy_mod() > get_max_healthy() ) {
4655 } else if( get_healthy_mod() < -200 ) {
4656 set_healthy_mod( -200 );
4657 }
4658
4659 // Active leukocyte breeder will keep your health near 100
4660 int effective_healthy_mod = get_healthy_mod();
4662 // Side effect: dependency
4663 mod_healthy_mod( -50, -200 );
4664 effective_healthy_mod = 100;
4665 }
4666
4667 // Health tends toward healthy_mod.
4668 // For small differences, it changes 4 points per day
4669 // For large ones, up to ~40% of the difference per day
4670 int health_change = effective_healthy_mod - get_healthy() + external_modifiers;
4671 mod_healthy( sgn( health_change ) * std::max( 1, std::abs( health_change ) / 10 ) );
4672
4673 // And healthy_mod decays over time.
4674 // Slowly near 0, but it's hard to overpower it near +/-100
4675 set_healthy_mod( std::round( get_healthy_mod() * 0.95f ) );
4676
4677 add_msg( m_debug, "Health: %d, Health mod: %d", get_healthy(), get_healthy_mod() );
4678}
static const bionic_id bio_leukocyte("bio_leukocyte")
int get_max_healthy() const
Definition: character.cpp:4567
@ AEP_SICK
Definition: enums.h:141

References add_msg(), AEP_SICK, bio_leukocyte, get_healthy(), get_healthy_mod(), get_max_healthy(), has_active_bionic(), has_artifact_with(), m_debug, mod_healthy(), mod_healthy_mod(), set_healthy_mod(), and sgn().

Referenced by update_body().

◆ update_morale()

void Character::update_morale ( )

Ticks down morale counters and removes them.

Definition at line 9002 of file character.cpp.

9003{
9004 morale->decay( 1_minutes );
9006}

References apply_persistent_morale(), and morale.

Referenced by process_turn().

◆ update_needs()

void Character::update_needs ( int  rate_multiplier)

Increases hunger, thirst, fatigue and stimulants wearing off.

rate_multiplier is for retroactive updates.

Definition at line 4800 of file character.cpp.

4801{
4802 const int current_stim = get_stim();
4803 // Hunger, thirst, & fatigue up every 5 minutes
4805 // No food/thirst/fatigue clock at all
4806 const bool debug_ls = has_trait( trait_DEBUG_LS );
4807 // No food/thirst, capped fatigue clock (only up to tired)
4808 const bool npc_no_food = is_npc() && get_option<bool>( "NO_NPC_FOOD" );
4809 const bool asleep = !sleep.is_null();
4810 const bool lying = asleep || has_effect( effect_lying_down ) ||
4812
4813 needs_rates rates = calc_needs_rates();
4814
4815 const bool wasnt_fatigued = get_fatigue() <= fatigue_levels::dead_tired;
4816 // Don't increase fatigue if sleeping or trying to sleep or if we're at the cap.
4817 if( get_fatigue() < 1050 && !asleep && !debug_ls ) {
4818 if( rates.fatigue > 0.0f ) {
4819 int fatigue_roll = roll_remainder( rates.fatigue * rate_multiplier );
4820 mod_fatigue( fatigue_roll );
4821
4822 // Synaptic regen bionic stops SD while awake and boosts it while sleeping
4824 // fatigue_roll should be around 1 - so the counter increases by 1 every minute on average,
4825 // but characters who need less sleep will also get less sleep deprived, and vice-versa.
4826
4827 // Note: Since needs are updated in 5-minute increments, we have to multiply the roll again by
4828 // 5. If rate_multiplier is > 1, fatigue_roll will be higher and this will work out.
4829 mod_sleep_deprivation( fatigue_roll * 5 );
4830 }
4831
4832 if( npc_no_food && get_fatigue() > fatigue_levels::tired ) {
4833 set_fatigue( static_cast<int>( fatigue_levels::tired ) );
4834 }
4835 if( npc_no_food ) {
4837 }
4838 }
4839 } else if( asleep && rates.recovery > 0.0f ) {
4840 int recovered = roll_remainder( rates.recovery * rate_multiplier );
4841 // Hibernation prevents waking up until you're hungry or thirsty
4842 if( get_fatigue() - recovered < -20 && !is_hibernating() ) {
4843 // Should be wake up, but that could prevent some retroactive regeneration
4844 sleep.set_duration( 1_turns );
4845 mod_fatigue( -25 );
4846 } else {
4848 recovered *= .5;
4849 }
4850 mod_fatigue( -recovered );
4851
4852 float rest_modifier = 1.0f;
4853 // Bionic doubles the base regen
4855 rest_modifier += 1.0f;
4856 }
4858 rest_modifier += 0.2f;
4859 }
4860
4861 const character_funcs::comfort_level comfort =
4863
4864 // Best possible bed increases recovery by 30% of base
4866 rest_modifier += 0.3f;
4867 } else if( comfort >= character_funcs::comfort_level::comfortable ) {
4868 rest_modifier += 0.2f;
4870 rest_modifier += 0.1f;
4871 }
4872
4873 // 6 hours of sleep per day will let you avoid deprivation
4874 // 4 hours if on great bed plus melatonin
4875 // Math: 5 (fatigue to minutes), 3 (1:3 sleep to waking),
4876 // 2 (legacy sleep non-linearity thing)
4877 mod_sleep_deprivation( -rest_modifier * ( recovered * 3.0f * 5.0f / 2.0f ) );
4878
4879 }
4880 }
4881 if( is_player() && wasnt_fatigued && get_fatigue() > fatigue_levels::dead_tired && !lying ) {
4882 if( !activity ) {
4883 add_msg_if_player( m_warning, _( "You're feeling tired. %s to lie down for sleep." ),
4884 press_x( ACTION_SLEEP ) );
4885 } else {
4886 g->cancel_activity_query( _( "You're feeling tired." ) );
4887 }
4888 }
4889
4890 if( current_stim < 0 ) {
4891 set_stim( std::min( current_stim + rate_multiplier, 0 ) );
4892 } else if( current_stim > 0 ) {
4893 set_stim( std::max( current_stim - rate_multiplier, 0 ) );
4894 }
4895
4896 if( get_painkiller() > 0 ) {
4897 mod_painkiller( -std::min( get_painkiller(), rate_multiplier ) );
4898 }
4899
4900 // Huge folks take penalties for cramming themselves in vehicles
4901 if( in_vehicle && ( get_size() == MS_HUGE )
4903 vehicle *veh = veh_pointer_or_null( get_map().veh_at( pos() ) );
4904 // it's painful to work the controls, but passengers in open topped vehicles are fine
4905 if( veh && ( veh->enclosed_at( pos() ) || veh->player_in_control( *this->as_player() ) ) ) {
4907 _( "You're cramping up from stuffing yourself in this vehicle." ) );
4908 if( is_npc() ) {
4909 npc &as_npc = dynamic_cast<npc &>( *this );
4910 as_npc.complain_about( "cramped_vehicle", 1_hours, "<cramped_vehicle>", false );
4911 }
4912
4913 mod_pain( rng( 4, 6 ) );
4914 focus_pool -= 1;
4915 }
4916 }
4917}
std::string press_x(action_id act)
Definition: action.cpp:458
@ ACTION_SLEEP
Open sleep menu.
Definition: action.h:205
static const efftype_id effect_melatonin_supplements("melatonin")
static const trait_id trait_DEBUG_LS("DEBUG_LS")
static const bionic_id bio_synaptic_regen("bio_synaptic_regen")
static const efftype_id effect_lying_down("lying_down")
needs_rates calc_needs_rates() const
Definition: character.cpp:4918
virtual void mod_sleep_deprivation(int nsleep_deprivation)
Definition: character.cpp:4459
virtual npc * as_npc()
Definition: creature.h:110
bool complain_about(const std::string &issue, const time_duration &dur, const std::string &speech, bool force=false, sounds::sound_t priority=sounds::sound_t::speech)
Definition: npcmove.cpp:4568
bool enclosed_at(const tripoint &pos)
Definition: vehicle.cpp:6307
comfort_response_t base_comfort_value(const Character &who, const tripoint &p)
Rate point's ability to serve as a bed.

References _, ACT_TRY_SLEEP, ACTION_SLEEP, activity, Creature::add_msg_if_player(), Creature::as_npc(), character_funcs::base_comfort_value(), bio_synaptic_regen, calc_needs_rates(), character_funcs::comfortable, npc::complain_about(), dead_tired, effect_lying_down, effect_melatonin_supplements, effect_narcosis, effect_recently_coughed, effect_sleep, vehicle::enclosed_at(), needs_rates::fatigue, focus_pool, g, Creature::get_effect(), get_fatigue(), get_map(), get_painkiller(), get_size(), get_stim(), has_active_bionic(), Creature::has_effect(), has_trait(), player_activity::id(), in_vehicle, is_hibernating(), Creature::is_npc(), Creature::is_player(), character_funcs::comfort_response_t::level, m_bad, m_warning, mod_fatigue(), mod_pain(), mod_painkiller(), mod_sleep_deprivation(), MS_HUGE, vehicle::player_in_control(), pos(), press_x(), needs_rates::recovery, rng(), roll_remainder(), set_fatigue(), set_sleep_deprivation(), set_stim(), sleep, character_funcs::slightly_comfortable, tired, trait_DEBUG_LS, trait_NOPAIN, veh_pointer_or_null(), and character_funcs::very_comfortable.

Referenced by update_body().

◆ update_stamina()

void Character::update_stamina ( int  turns)

Regenerates stamina.

Definition at line 7166 of file character.cpp.

7167{
7168 static const std::string player_base_stamina_regen_rate( "PLAYER_BASE_STAMINA_REGEN_RATE" );
7169 static const std::string stamina_regen_modifier( "stamina_regen_modifier" );
7170 const float base_regen_rate = get_option<float>( player_base_stamina_regen_rate );
7171 const int current_stim = get_stim();
7172 float stamina_recovery = 0.0f;
7173 // Recover some stamina every turn.
7174 // max stamina modifers from mutation also affect stamina multi
7175 float stamina_multiplier = 1.0f + mutation_value( stamina_regen_modifier ) +
7176 ( mutation_value( "max_stamina_modifier" ) - 1.0f ) +
7178 // But mouth encumbrance interferes, even with mutated stamina.
7179 stamina_recovery += stamina_multiplier * std::max( 1.0f,
7180 base_regen_rate - ( encumb( bp_mouth ) / 5.0f ) );
7181 // TODO: recovering stamina causes hunger/thirst/fatigue.
7182 // TODO: Tiredness slowing recovery
7183
7184 // stim recovers stamina (or impairs recovery)
7185 if( current_stim > 0 ) {
7186 // TODO: Make stamina recovery with stims cost health
7187 stamina_recovery += std::min( 5.0f, current_stim / 15.0f );
7188 } else if( current_stim < 0 ) {
7189 // Affect it less near 0 and more near full
7190 // Negative stim kill at -200
7191 // At -100 stim it inflicts -20 malus to regen at 100% stamina,
7192 // effectivly countering stamina gain of default 20,
7193 // at 50% stamina its -10 (50%), cuts by 25% at 25% stamina
7194 // FIXME: this formula is only suitable for advancing by 1 turn
7195 stamina_recovery += current_stim / 5.0f * get_stamina() / get_stamina_max();
7196 }
7197 stamina_recovery = std::max( 0.0f, stamina_recovery );
7198
7199 const int max_stam = get_stamina_max();
7200 if( get_power_level() >= 3_kJ && has_active_bionic( bio_gills ) ) {
7201 int bonus = std::min<int>( units::to_kilojoule( get_power_level() ) / 3,
7202 max_stam - get_stamina() - stamina_recovery * turns );
7203 // so the effective recovery is up to 5x default
7204 bonus = std::min( bonus, 4 * static_cast<int>( base_regen_rate ) );
7205 if( bonus > 0 ) {
7206 stamina_recovery += bonus;
7207 bonus /= 10;
7208 bonus = std::max( bonus, 1 );
7210 }
7211 }
7212
7213 mod_stamina( roll_remainder( stamina_recovery * turns ) );
7214 add_msg( m_debug, "Stamina recovery: %d", roll_remainder( stamina_recovery * turns ) );
7215 // Cap at max
7216 set_stamina( std::min( std::max( get_stamina(), 0 ), max_stam ) );
7217}
static const bionic_id bio_gills("bio_gills")

References add_msg(), bio_gills, bonus_from_enchantments(), bp_mouth, encumb(), units::from_kilojoule(), get_power_level(), get_stamina(), get_stamina_max(), get_stim(), has_active_bionic(), m_debug, mod_power_level(), mod_stamina(), mutation_value(), roll_remainder(), set_stamina(), enchant_vals::STAMINA_REGEN, and units::to_kilojoule().

Referenced by update_body().

◆ update_stomach()

void Character::update_stomach ( const time_point from,
const time_point to 
)

Updates the stomach to give accurate hunger messages.

Definition at line 4757 of file character.cpp.

4758{
4759 const needs_rates rates = calc_needs_rates();
4760 // No food/thirst/fatigue clock at all
4761 const bool debug_ls = has_trait( trait_DEBUG_LS );
4762 // No food/thirst, capped fatigue clock (only up to tired)
4763 const bool npc_no_food = is_npc() && get_option<bool>( "NO_NPC_FOOD" );
4764 const bool foodless = debug_ls || npc_no_food;
4765 const bool mouse = has_trait( trait_NO_THIRST );
4766 const bool mycus = has_trait( trait_M_DEPENDENT );
4767 const float kcal_per_time = bmr() / ( 12.0f * 24.0f );
4768 const int five_mins = ticks_between( from, to, 5_minutes );
4769
4770 if( five_mins > 0 ) {
4771 // Digest nutrients in stomach
4772 food_summary digested_to_body = stomach.digest( rates, five_mins );
4773 // Apply nutrients, unless this is an NPC and NO_NPC_FOOD is enabled.
4774 if( !npc_no_food ) {
4775 mod_stored_kcal( digested_to_body.nutr.kcal );
4776 vitamins_mod( digested_to_body.nutr.vitamins, false );
4777 }
4778 if( !foodless && rates.hunger > 0.0f ) {
4779 // instead of hunger keeping track of how you're living, burn calories instead
4780 mod_stored_kcal( -roll_remainder( five_mins * kcal_per_time ) );
4781 }
4782 }
4783
4784 if( !foodless && rates.thirst > 0.0f ) {
4785 mod_thirst( roll_remainder( rates.thirst * five_mins ) );
4786 }
4787
4788 if( npc_no_food ) {
4789 set_thirst( static_cast<int>( thirst_levels::hydrated ) );
4791 }
4792
4793 // Mycus and Metabolic Rehydration makes thirst unnecessary
4794 // since water is not limited by intake but by absorption, we can just set thirst to zero
4795 if( mycus || mouse ) {
4796 set_thirst( 0 );
4797 }
4798}
static const trait_id trait_NO_THIRST("NO_THIRST")
static const trait_id trait_M_DEPENDENT("M_DEPENDENT")
void vitamins_mod(const std::map< vitamin_id, int > &, bool capped=true)
food_summary digest(const needs_rates &metabolic_rates, int five_mins)
Processes food and outputs nutrients that are finished processing Metabolic rates are required becaus...
Definition: stomach.cpp:132
int mycus(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:1440
nutrients nutr
Definition: stomach.h:53
std::map< vitamin_id, int > vitamins
vitamins potentially provided by this comestible (if any)
Definition: stomach.h:21

References bmr(), calc_needs_rates(), stomach_contents::digest(), has_trait(), needs_rates::hunger, hydrated, Creature::is_npc(), nutrients::kcal, max_stored_kcal(), mod_stored_kcal(), mod_thirst(), iuse::mycus(), food_summary::nutr, roll_remainder(), set_stored_kcal(), set_thirst(), stomach, needs_rates::thirst, ticks_between(), trait_DEBUG_LS, trait_M_DEPENDENT, trait_NO_THIRST, nutrients::vitamins, and vitamins_mod().

Referenced by update_body().

◆ update_type_of_scent() [1/2]

void Character::update_type_of_scent ( bool  init = false)

Definition at line 8728 of file character.cpp.

8729{
8730 scenttype_id new_scent = scenttype_id( "sc_human" );
8731 for( const trait_id &mut : get_mutations() ) {
8732 if( mut.obj().scent_typeid ) {
8733 new_scent = mut.obj().scent_typeid.value();
8734 }
8735 }
8736
8737 if( !init && new_scent != get_type_of_scent() ) {
8738 g->scent.reset();
8739 }
8740 set_type_of_scent( new_scent );
8741}
scenttype_id get_type_of_scent() const
Definition: character.cpp:8761
Definition: init.h:178

References g, get_mutations(), get_type_of_scent(), mutation_branch::scent_typeid, and set_type_of_scent().

Referenced by on_mutation_gain(), on_mutation_loss(), and update_type_of_scent().

◆ update_type_of_scent() [2/2]

void Character::update_type_of_scent ( const trait_id mut,
bool  gain = true 
)

Definition at line 8743 of file character.cpp.

8744{
8745 const std::optional<scenttype_id> &mut_scent = mut->scent_typeid;
8746 if( mut_scent ) {
8747 if( gain && mut_scent.value() != get_type_of_scent() ) {
8748 set_type_of_scent( mut_scent.value() );
8749 g->scent.reset();
8750 } else {
8752 }
8753 }
8754}
std::optional< scenttype_id > scent_typeid
What do you smell like.
Definition: mutation.h:159

References g, get_type_of_scent(), mutation_branch::scent_typeid, set_type_of_scent(), and update_type_of_scent().

◆ update_vitamins()

void Character::update_vitamins ( const vitamin_id vit)

Set vitamin deficiency/excess disease states dependent upon current vitamin levels.

Definition at line 8802 of file character.cpp.

8803{
8804 if( is_npc() ) {
8805 return; // NPCs cannot develop vitamin diseases
8806 }
8807
8808 efftype_id def = vit.obj().deficiency();
8809 efftype_id exc = vit.obj().excess();
8810
8811 int lvl = vit.obj().severity( vitamin_get( vit ) );
8812 if( lvl <= 0 ) {
8813 remove_effect( def );
8814 }
8815 if( lvl >= 0 ) {
8816 remove_effect( exc );
8817 }
8818 if( lvl > 0 ) {
8819 if( has_effect( def, num_bp ) ) {
8820 get_effect( def, num_bp ).set_intensity( lvl, true );
8821 } else {
8822 add_effect( def, 1_turns, num_bp, lvl );
8823 }
8824 }
8825 if( lvl < 0 ) {
8826 if( has_effect( exc, num_bp ) ) {
8827 get_effect( exc, num_bp ).set_intensity( -lvl, true );
8828 } else {
8829 add_effect( exc, 1_turns, num_bp, -lvl );
8830 }
8831 }
8832}
int vitamin_get(const vitamin_id &vit) const
Check current level of a vitamin.
int set_intensity(int val, bool alert=false)
Sets intensity of effect capped by range [1..max_intensity].
Definition: effect.cpp:858
const efftype_id & deficiency() const
Disease effect with increasing intensity proportional to vitamin deficiency.
Definition: vitamin.h:57
const efftype_id & excess() const
Disease effect with increasing intensity proportional to vitamin excess.
Definition: vitamin.h:62
int severity(int qty) const
Get intensity of deficiency or zero if not deficient for specified qty.
Definition: vitamin.cpp:39

References Creature::add_effect(), vitamin::deficiency(), vitamin::excess(), Creature::get_effect(), Creature::has_effect(), Creature::is_npc(), num_bp, string_id< T >::obj(), Creature::remove_effect(), effect::set_intensity(), vitamin::severity(), and vitamin_get().

Referenced by vitamin_mod().

◆ use_amount()

std::list< item > Character::use_amount ( itype_id  it,
int  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 9631 of file character.cpp.

9633{
9634 std::list<item> ret;
9635 if( primary_weapon().use_amount( it, quantity, ret ) ) {
9636 remove_weapon();
9637 }
9638 for( auto a = worn.begin(); a != worn.end() && quantity > 0; ) {
9639 if( a->use_amount( it, quantity, ret, filter ) ) {
9640 a->on_takeoff( *this );
9641 a = worn.erase( a );
9642 } else {
9643 ++a;
9644 }
9645 }
9646 if( quantity <= 0 ) {
9647 return ret;
9648 }
9649 std::list<item> tmp = inv.use_amount( it, quantity, filter );
9650 ret.splice( ret.end(), tmp );
9651 return ret;
9652}
std::list< item > use_amount(itype_id it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: character.cpp:9631
std::list< item > use_amount(itype_id it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: inventory.cpp:855

References a, inv, primary_weapon(), remove_weapon(), cata::hash64_detail::ret, use_amount(), inventory::use_amount(), and worn.

Referenced by computer_session::action_srcf_elevator(), iexamine::cardreader(), iexamine::cardreader_robofac(), player::consume_items(), game::find_or_make_stairs(), hack_attempt(), monexamine::mech_hack(), iexamine::pedestal_temple(), activity_handlers::plant_seed_finish(), vehicle::reload_seeds(), talk_effect_fun_t::set_consume_item(), talk_effect_fun_t::set_u_sell_item(), sinkhole_safety_roll(), npc_trading::transfer_items(), and use_amount().

◆ use_charges()

std::list< item > Character::use_charges ( const itype_id what,
int  qty,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 9663 of file character.cpp.

9665{
9666 std::list<item> res;
9667
9668 if( qty <= 0 ) {
9669 return res;
9670
9671 } else if( what == itype_toolset ) {
9673 return res;
9674
9675 } else if( what == itype_fire ) {
9676 use_fire( qty );
9677 return res;
9678
9679 } else if( what == itype_bio_armor ) {
9680 float mod_qty = 0;
9681 float efficiency = 1;
9682 for( const bionic &bio : *my_bionics ) {
9683 if( bio.powered && bio.info().has_flag( flag_BIONIC_ARMOR_INTERFACE ) ) {
9684 efficiency = std::max( efficiency, bio.info().fuel_efficiency );
9685 }
9686 }
9687 if( efficiency == 1 ) {
9688 debugmsg( "Player lacks a bionic armor interface with fuel efficiency field." );
9689 }
9690 mod_qty = qty / efficiency;
9692 return res;
9693
9694 } else if( what == itype_UPS ) {
9695 if( is_mounted() && mounted_creature.get()->has_flag( MF_RIDEABLE_MECH ) &&
9696 mounted_creature.get()->battery_item ) {
9697 auto mons = mounted_creature.get();
9698 int power_drain = std::min( mons->battery_item->ammo_remaining(), qty );
9699 mons->use_mech_power( -power_drain );
9700 qty -= std::min( qty, power_drain );
9701 return res;
9702 }
9703 if( has_power() && has_active_bionic( bio_ups ) ) {
9704 int bio = std::min( units::to_kilojoule( get_power_level() ), qty );
9706 qty -= std::min( qty, bio );
9707 }
9708
9709 int adv = charges_of( itype_adv_UPS_off, static_cast<int>( std::ceil( qty * 0.6 ) ) );
9710 if( adv > 0 ) {
9711 std::list<item> found = use_charges( itype_adv_UPS_off, adv );
9712 res.splice( res.end(), found );
9713 qty -= std::min( qty, static_cast<int>( adv / 0.6 ) );
9714 }
9715
9716 int ups = charges_of( itype_UPS_off, qty );
9717 if( ups > 0 ) {
9718 std::list<item> found = use_charges( itype_UPS_off, ups );
9719 res.splice( res.end(), found );
9720 qty -= std::min( qty, ups );
9721 }
9722 return res;
9723
9724 }
9725
9726 std::vector<item *> del;
9727
9728 bool has_tool_with_UPS = false;
9729 visit_items( [this, &what, &qty, &res, &del, &has_tool_with_UPS, &filter]( item * e ) {
9730 if( e->use_charges( what, qty, res, pos(), filter ) ) {
9731 del.push_back( e );
9732 }
9733 if( filter( *e ) && e->typeId() == what && e->has_flag( flag_USE_UPS ) ) {
9734 has_tool_with_UPS = true;
9735 }
9736 return qty > 0 ? VisitResponse::SKIP : VisitResponse::ABORT;
9737 } );
9738
9739 for( auto e : del ) {
9740 remove_item( *e );
9741 }
9742
9743 if( has_tool_with_UPS ) {
9744 use_charges( itype_UPS, qty );
9745 }
9746
9747 return res;
9748}
static const itype_id itype_toolset("toolset")
static const itype_id itype_adv_UPS_off("adv_UPS_off")
static const bionic_id bio_ups("bio_ups")
static const itype_id itype_UPS_off("UPS_off")
void use_fire(int quantity)
Definition: character.cpp:9814
bool use_charges(const itype_id &what, int &qty, std::list< item > &used, const tripoint &pos, const std::function< bool(const item &)> &filter=return_true< item >)
Consumes specified charges (or fewer) from this and any contained items.
Definition: item.cpp:8632

References ABORT, bio_ups, visitable< Character >::charges_of(), debugmsg, flag_BIONIC_ARMOR_INTERFACE, flag_USE_UPS(), units::from_kilojoule(), get_power_level(), has_active_bionic(), item::has_flag(), has_power(), is_mounted(), itype_adv_UPS_off, itype_bio_armor, itype_fire, itype_toolset, itype_UPS, itype_UPS_off, MF_RIDEABLE_MECH, mod_power_level(), mounted_creature, my_bionics, pos(), visitable< Character >::remove_item(), SKIP, units::to_kilojoule(), item::typeId(), item::use_charges(), use_charges(), use_fire(), and visitable< Character >::visit_items().

Referenced by iexamine::arcfurnace_empty(), consume_charges(), player::consume_items(), consume_med(), consume_remote_fuel(), player::consume_tools(), eat(), iuse::ecig(), iexamine::fertilize_plant(), ranged::fire_gun(), iexamine::fireplace(), iexamine::fvat_empty(), activity_handlers::gunmod_add_finish(), hack_attempt(), iexamine::keg(), iexamine::kiln_empty(), monexamine::pay_bot(), iexamine::pay_gas(), activity_handlers::plant_seed_finish(), process_items(), iexamine::reload_furniture(), vehicle::reload_seeds(), talk_effect_fun_t::set_bulk_trade_accept(), talk_effect_fun_t::set_consume_item(), talk_effect_fun_t::set_u_sell_item(), smoker_activate(), npc_trading::transfer_items(), try_consume(), try_start_hacking(), consume_drug_iuse::use(), place_monster_iuse::use(), cauterize_actor::use(), use_charges(), use_charges_if_avail(), use_fire(), and iexamine::vending().

◆ use_charges_if_avail()

bool Character::use_charges_if_avail ( const itype_id it,
int  quantity 
)

Definition at line 9654 of file character.cpp.

9655{
9656 if( has_charges( it, quantity ) ) {
9657 use_charges( it, quantity );
9658 return true;
9659 }
9660 return false;
9661}

References has_charges(), and use_charges().

Referenced by iuse::arrow_flammable(), iuse::firecracker(), activity_handlers::game_do_turn(), iuse::meth(), iuse::note_bionics(), item::process_tool(), item::reload(), iuse::smoking(), suffer_from_asthma(), and iuse_transform::use().

◆ use_fire()

void Character::use_fire ( int  quantity)

Definition at line 9814 of file character.cpp.

9815{
9816 //Okay, so checks for nearby fires first,
9817 //then held lit torch or candle, bionic tool/lighter/laser
9818 //tries to use 1 charge of lighters, matches, flame throwers
9819 //If there is enough power, will use power of one activation of the bio_lighter, bio_tools and bio_laser
9820 // (home made, military), hotplate, welder in that order.
9821 // bio_lighter, bio_laser, bio_tools, has_active_bionic("bio_tools"
9822
9823 if( get_map().has_nearby_fire( pos() ) ) {
9824 return;
9825 } else if( has_item_with_flag( "FIRE" ) ) {
9826 return;
9827 } else if( has_item_with_flag( "FIRESTARTER" ) ) {
9828 auto firestarters = all_items_with_flag( "FIRESTARTER" );
9829 for( auto &i : firestarters ) {
9830 if( has_charges( i->typeId(), quantity ) ) {
9831 use_charges( i->typeId(), quantity );
9832 return;
9833 }
9834 }
9835 } else if( has_active_bionic( bio_tools ) && get_power_level() > quantity * 5_kJ ) {
9836 mod_power_level( -quantity * 5_kJ );
9837 return;
9838 } else if( has_bionic( bio_lighter ) && get_power_level() > quantity * 5_kJ ) {
9839 mod_power_level( -quantity * 5_kJ );
9840 return;
9841 } else if( has_bionic( bio_laser ) && get_power_level() > quantity * 5_kJ ) {
9842 mod_power_level( -quantity * 5_kJ );
9843 return;
9844 }
9845}

References all_items_with_flag(), bio_laser, bio_lighter, bio_tools, get_map(), get_power_level(), has_active_bionic(), has_bionic(), has_charges(), has_item_with_flag(), mod_power_level(), pos(), and use_charges().

Referenced by use_charges().

◆ used_weapon() [1/2]

item & Character::used_weapon ( )

Legacy code hack, don't use.

Returns the null item if martial art forces unarmed, otherwise primary_weapon. Use wielded_items instead.

Definition at line 144 of file melee.cpp.

145{
146 return const_cast<item &>( const_cast<const Character *>( this )->used_weapon() );
147}

References used_weapon().

Referenced by get_melee_hit_base(), melee_attack(), unarmed_attack(), and used_weapon().

◆ used_weapon() [2/2]

const item & Character::used_weapon ( ) const

Definition at line 139 of file melee.cpp.

140{
141 return martial_arts_data->selected_force_unarmed() ? null_item_reference() : primary_weapon();
142}

References martial_arts_data, null_item_reference(), and primary_weapon().

◆ valid_aoe_technique() [1/2]

bool Character::valid_aoe_technique ( Creature t,
const ma_technique technique 
)
private

Check if an area-of-effect technique has valid targets.

Definition at line 1277 of file melee.cpp.

1278{
1279 std::vector<Creature *> dummy_targets;
1280 return valid_aoe_technique( t, technique, dummy_targets );
1281}

References valid_aoe_technique().

Referenced by perform_technique(), pick_technique(), and valid_aoe_technique().

◆ valid_aoe_technique() [2/2]

bool Character::valid_aoe_technique ( Creature t,
const ma_technique technique,
std::vector< Creature * > &  targets 
)
private

Definition at line 1283 of file melee.cpp.

1285{
1286 if( technique.aoe.empty() ) {
1287 return false;
1288 }
1289
1290 // pre-computed matrix of adjacent squares
1291 std::array<int, 9> offset_a = { {0, -1, -1, 1, 0, -1, 1, 1, 0 } };
1292 std::array<int, 9> offset_b = { {-1, -1, 0, -1, 0, 1, 0, 1, 1 } };
1293
1294 // filter the values to be between -1 and 1 to avoid indexing the array out of bounds
1295 int dy = std::max( -1, std::min( 1, t.posy() - posy() ) );
1296 int dx = std::max( -1, std::min( 1, t.posx() - posx() ) );
1297 int lookup = dy + 1 + 3 * ( dx + 1 );
1298
1299 //wide hits all targets adjacent to the attacker and the target
1300 if( technique.aoe == "wide" ) {
1301 //check if either (or both) of the squares next to our target contain a possible victim
1302 //offsets are a pre-computed matrix allowing us to quickly lookup adjacent squares
1303 tripoint left = pos() + tripoint( offset_a[lookup], offset_b[lookup], 0 );
1304 tripoint right = pos() + tripoint( offset_b[lookup], -offset_a[lookup], 0 );
1305
1306 monster *const mon_l = g->critter_at<monster>( left );
1307 if( mon_l && mon_l->friendly == 0 ) {
1308 targets.push_back( mon_l );
1309 }
1310 monster *const mon_r = g->critter_at<monster>( right );
1311 if( mon_r && mon_r->friendly == 0 ) {
1312 targets.push_back( mon_r );
1313 }
1314
1315 npc *const npc_l = g->critter_at<npc>( left );
1316 npc *const npc_r = g->critter_at<npc>( right );
1317 if( npc_l && npc_l->is_enemy() ) {
1318 targets.push_back( npc_l );
1319 }
1320 if( npc_r && npc_r->is_enemy() ) {
1321 targets.push_back( npc_r );
1322 }
1323 if( !targets.empty() ) {
1324 return true;
1325 }
1326 }
1327
1328 if( technique.aoe == "impale" ) {
1329 // Impale hits the target and a single target behind them
1330 // Check if the square cardinally behind our target, or to the left / right,
1331 // contains a possible target.
1332 tripoint left = t.pos() + tripoint( offset_a[lookup], offset_b[lookup], 0 );
1333 tripoint target_pos = t.pos() + ( t.pos() - pos() );
1334 tripoint right = t.pos() + tripoint( offset_b[lookup], -offset_b[lookup], 0 );
1335
1336 monster *const mon_l = g->critter_at<monster>( left );
1337 monster *const mon_t = g->critter_at<monster>( target_pos );
1338 monster *const mon_r = g->critter_at<monster>( right );
1339 if( mon_l && mon_l->friendly == 0 ) {
1340 targets.push_back( mon_l );
1341 }
1342 if( mon_t && mon_t->friendly == 0 ) {
1343 targets.push_back( mon_t );
1344 }
1345 if( mon_r && mon_r->friendly == 0 ) {
1346 targets.push_back( mon_r );
1347 }
1348
1349 npc *const npc_l = g->critter_at<npc>( left );
1350 npc *const npc_t = g->critter_at<npc>( target_pos );
1351 npc *const npc_r = g->critter_at<npc>( right );
1352 if( npc_l && npc_l->is_enemy() ) {
1353 targets.push_back( npc_l );
1354 }
1355 if( npc_t && npc_t->is_enemy() ) {
1356 targets.push_back( npc_t );
1357 }
1358 if( npc_r && npc_r->is_enemy() ) {
1359 targets.push_back( npc_r );
1360 }
1361 if( !targets.empty() ) {
1362 return true;
1363 }
1364 }
1365
1366 if( targets.empty() && technique.aoe == "spin" ) {
1367 for( const tripoint &tmp : g->m.points_in_radius( pos(), 1 ) ) {
1368 if( tmp == t.pos() ) {
1369 continue;
1370 }
1371 monster *const mon = g->critter_at<monster>( tmp );
1372 if( mon && mon->friendly == 0 ) {
1373 targets.push_back( mon );
1374 }
1375 npc *const np = g->critter_at<npc>( tmp );
1376 if( np && np->is_enemy() ) {
1377 targets.push_back( np );
1378 }
1379 }
1380 //don't trigger circle for fewer than 2 targets
1381 if( targets.size() < 2 ) {
1382 targets.clear();
1383 } else {
1384 return true;
1385 }
1386 }
1387 return false;
1388}
bool is_enemy() const
Definition: npc.cpp:2047

References ma_technique::aoe, monster::friendly, g, npc::is_enemy(), left, Creature::pos(), pos(), Creature::posx(), posx(), Creature::posy(), posy(), and right.

◆ visibility()

int Character::visibility ( bool  check_color = false,
int  stillness = 0 
) const

Checks is_invisible() as well as other factors.

Definition at line 6291 of file character.cpp.

6292{
6293 // 0-100 %
6294 if( is_invisible() ) {
6295 return 0;
6296 }
6297 // TODO:
6298 // if ( dark_clothing() && light check ...
6299 int stealth_modifier = std::floor( mutation_value( "stealth_modifier" ) );
6300 return clamp( 100 - stealth_modifier, 40, 160 );
6301}
bool is_invisible() const
Definition: character.cpp:6281

References clamp(), is_invisible(), and mutation_value().

◆ visible_mutations()

std::string Character::visible_mutations ( int  visibility_cap) const

Returns an enumeration of visible mutations with colors.

Definition at line 1728 of file mutation.cpp.

1729{
1730 const std::vector<trait_id> &my_muts = get_mutations();
1731 const std::string trait_str = enumerate_as_string( my_muts.begin(), my_muts.end(),
1732 [visibility_cap ]( const trait_id & pr ) -> std::string {
1733 const auto &mut_branch = pr.obj();
1734 // Finally some use for visibility trait of mutations
1735 if( mut_branch.visibility > 0 && mut_branch.visibility >= visibility_cap )
1736 {
1737 return colorize( mut_branch.name(), mut_branch.get_display_color() );
1738 }
1739
1740 return std::string();
1741 } );
1742 return trait_str;
1743}

References enumerate_as_string(), and get_mutations().

Referenced by npc::print_info(), and short_description_parts().

◆ vitamin_get()

int Character::vitamin_get ( const vitamin_id vit) const

Check current level of a vitamin.

Accesses level of a given vitamin. If the vitamin_id specified does not exist then this function simply returns 0.

Parameters
vitID of vitamin to check level for.
Returns
current level for specified vitamin

Definition at line 580 of file consumption.cpp.

581{
582 if( get_option<bool>( "NO_VITAMINS" ) && vit->type() == vitamin_type::VITAMIN ) {
583 return 0;
584 }
585
586 const auto &v = vitamin_levels.find( vit );
587 return v != vitamin_levels.end() ? v->second : 0;
588}
const vitamin_type & type() const
Definition: vitamin.h:40
@ VITAMIN
Definition: vitamin.h:19

References vitamin::type(), VITAMIN, and vitamin_levels.

Referenced by debug_menu::character_edit_menu(), eff_fun_mutating(), and update_vitamins().

◆ vitamin_mod()

int Character::vitamin_mod ( const vitamin_id vit,
int  qty,
bool  capped = true 
)

Add or subtract vitamins from character storage pools.

Parameters
vitID of vitamin to modify
qtyamount by which to adjust vitamin (negative values are permitted)
cappedif true prevent vitamins which can accumulate in excess from doing so
Returns
adjusted level for the vitamin or zero if vitamin does not exist

Definition at line 548 of file consumption.cpp.

549{
550 if( !vit.is_valid() ) {
551 debugmsg( "Vitamin with id %s does not exist, and cannot be modified", vit.str() );
552 return 0;
553 }
554 // What's going on here? Emplace returns either an iterator to the inserted
555 // item or, if it already exists, an iterator to the (unchanged) extant item
556 // (Okay, technically it returns a pair<iterator, bool>, the iterator is what we want)
557 auto it = vitamin_levels.emplace( vit, 0 ).first;
558 const vitamin &v = *it->first;
559
560 if( qty > 0 ) {
561 // Accumulations can never occur from food sources
562 it->second = std::min( it->second + qty, capped ? 0 : v.max() );
563 update_vitamins( vit );
564
565 } else if( qty < 0 ) {
566 it->second = std::max( it->second + qty, v.min() );
567 update_vitamins( vit );
568 }
569
570 return it->second;
571}
void update_vitamins(const vitamin_id &vit)
Set vitamin deficiency/excess disease states dependent upon current vitamin levels.
Definition: character.cpp:8802
int max() const
Upper bound for any accumulation of this vitamin.
Definition: vitamin.h:72
int min() const
Lower bound for deficiency of this vitamin.
Definition: vitamin.h:67

References debugmsg, string_id< T >::is_valid(), vitamin::max(), vitamin::min(), string_id< T >::str(), update_vitamins(), and vitamin_levels.

Referenced by eff_fun_bleed(), rooted(), suffer_from_other_mutations(), suffer_in_sunlight(), update_body(), consume_drug_iuse::use(), vitamin_set(), and vitamins_mod().

◆ vitamin_rate()

time_duration Character::vitamin_rate ( const vitamin_id vit) const

Get vitamin usage rate (minutes per unit) accounting for bionics, mutations and effects.

Definition at line 533 of file consumption.cpp.

534{
535 time_duration res = vit.obj().rate();
536
537 for( const auto &m : get_mutations() ) {
538 const auto &mut = m.obj();
539 auto iter = mut.vitamin_rates.find( vit );
540 if( iter != mut.vitamin_rates.end() ) {
541 res += iter->second;
542 }
543 }
544
545 return res;
546}
time_duration rate() const
Usage rate of vitamin (time to consume unit) Lower bound is zero whereby vitamin is not required (but...
Definition: vitamin.h:80

References get_mutations(), string_id< T >::obj(), and vitamin::rate().

Referenced by item::food_info(), update_body(), and consume_drug_iuse::use().

◆ vitamin_set()

bool Character::vitamin_set ( const vitamin_id vit,
int  qty 
)

Sets level of a vitamin or returns false if id given in vit does not exist.

Note
status effects are still set for deficiency/excess
Parameters
[in]vitID of vitamin to adjust quantity for
[in]qtyQuantity to set level to
Returns
false if given vitamin_id does not exist, otherwise true

Definition at line 590 of file consumption.cpp.

591{
592 auto v = vitamin_levels.find( vit );
593 if( v == vitamin_levels.end() ) {
594 return false;
595 }
596 vitamin_mod( vit, qty - v->second, false );
597
598 return true;
599}

References vitamin_levels, and vitamin_mod().

Referenced by debug_menu::character_edit_menu(), eff_fun_mutating(), and eff_fun_toxin_buildup().

◆ vitamins_mod()

void Character::vitamins_mod ( const std::map< vitamin_id, int > &  vitamins,
bool  capped = true 
)

Definition at line 573 of file consumption.cpp.

574{
575 for( auto vit : vitamins ) {
576 vitamin_mod( vit.first, vit.second, capped );
577 }
578}

References vitamin_mod().

Referenced by update_stomach().

◆ volume_capacity()

◆ volume_capacity_reduced_by()

units::volume Character::volume_capacity_reduced_by ( const units::volume mod,
const excluded_stacks without = {} 
) const

Definition at line 2675 of file character.cpp.

2677{
2679 return units::volume_max;
2680 }
2681
2683 for( const auto &i : worn ) {
2684 if( !without.count( &i ) ) {
2685 ret += i.get_storage();
2686 }
2687 }
2688 if( has_bionic( bio_storage ) ) {
2689 ret += 2_liter;
2690 }
2691 if( has_trait( trait_SHELL ) ) {
2692 ret += 4_liter;
2693 }
2695 ret += 6_liter;
2696 }
2697 if( has_trait( trait_PACKMULE ) ) {
2698 ret = ret * 1.4;
2699 }
2700 if( has_trait( trait_DISORGANIZED ) ) {
2701 ret = ret * 0.6;
2702 }
2703 return std::max( ret, 0_ml );
2704}
static const trait_id trait_SHELL("SHELL")
static const trait_id trait_DISORGANIZED("DISORGANIZED")
static const trait_id trait_PACKMULE("PACKMULE")
static const bionic_id bio_storage("bio_storage")
const volume volume_max
Definition: units_volume.h:21

References bio_storage, has_active_mutation(), has_bionic(), has_trait(), cata::hash64_detail::ret, trait_DEBUG_STORAGE, trait_DISORGANIZED, trait_PACKMULE, trait_SHELL, trait_SHELL2, units::volume_max, and worn.

Referenced by inventory_drop_selector::get_raw_stats(), pickup::reorder_for_dropping(), takeoff(), and volume_capacity().

◆ volume_carried()

◆ volume_carried_reduced_by()

units::volume Character::volume_carried_reduced_by ( const excluded_stacks without) const

Definition at line 2617 of file character.cpp.

2618{
2619 if( without.empty() ) {
2620 return inv.volume();
2621 } else {
2622 return inv.volume_without( without );
2623 }
2624}
units::volume volume_without(const excluded_stacks &without) const
Definition: inventory.cpp:1071

References inv, inventory::volume(), and inventory::volume_without().

Referenced by inventory_drop_selector::get_raw_stats().

◆ vomit()

void Character::vomit ( )

Handles Character vomiting effects.

Definition at line 7697 of file character.cpp.

7698{
7699 g->events().send<event_type::throws_up>( getID() );
7700
7701 map &here = get_map();
7702 if( get_effect_int( effect_fungus ) >= 3 ) {
7703 add_msg_player_or_npc( m_bad, _( "You vomit thousands of live spores!" ),
7704 _( "<npcname> vomits thousands of live spores!" ) );
7705 fungal_effects( *g, here ).fungalize( pos(), this );
7706 } else if( stomach.get_calories() > 0 || get_thirst() < 0 ) {
7707 add_msg_player_or_npc( m_bad, _( "You throw up heavily!" ), _( "<npcname> throws up heavily!" ) );
7708 here.add_field( character_funcs::pick_safe_adjacent_tile( *this ).value_or( pos() ), fd_bile, 1 );
7709 } else {
7710 return;
7711 }
7712
7713 if( !has_effect( effect_nausea ) ) { // Prevents never-ending nausea
7714 const effect dummy_nausea( &effect_nausea.obj(), 0_turns, bodypart_str_id::NULL_ID(), 1,
7716 add_effect( effect_nausea, std::max( dummy_nausea.get_max_duration() *
7717 stomach.get_calories() / 100, dummy_nausea.get_int_dur_factor() ) );
7718 }
7719
7720 stomach.empty();
7721 set_thirst( std::max( 0, get_thirst() ) );
7723 if( get_healthy_mod() > 0 ) {
7724 set_healthy_mod( 0 );
7725 }
7726
7727 moves -= 100;
7728 // get_effect is more correct than has_effect because of body parts
7729 effect &eff_foodpoison = get_effect( effect_foodpoison );
7730 if( eff_foodpoison ) {
7731 eff_foodpoison.mod_duration( -30_minutes );
7732 }
7733 effect &eff_drunk = get_effect( effect_drunk );
7734 if( eff_drunk ) {
7735 eff_drunk.mod_duration( rng( -10_minutes, -50_minutes ) );
7736 }
7740 // Don't wake up when just retching
7741 wake_up();
7742}
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_pkill2("pkill2")
static const efftype_id effect_bloated("bloated")
static const efftype_id effect_foodpoison("foodpoison")
static const efftype_id effect_pkill1("pkill1")
static const efftype_id effect_pkill3("pkill3")
void fungalize(const tripoint &p, Creature *origin=nullptr, double spore_chance=0.0)
field_type_id fd_bile
Definition: field_type.cpp:337
std::optional< tripoint > pick_safe_adjacent_tile(const Character &who)
Returns an unoccupied, safe adjacent point.

References _, Creature::add_effect(), Creature::add_msg_player_or_npc(), effect_bloated, effect_drunk, effect_foodpoison, effect_fungus, effect_nausea, effect_pkill1, effect_pkill2, effect_pkill3, stomach_contents::empty(), fd_bile, fungal_effects::fungalize(), g, stomach_contents::get_calories(), Creature::get_effect(), Creature::get_effect_int(), get_healthy_mod(), effect::get_int_dur_factor(), get_map(), effect::get_max_duration(), get_thirst(), getID(), Creature::has_effect(), m_bad, effect::mod_duration(), Creature::moves, string_id< body_part_type >::NULL_ID(), string_id< T >::obj(), character_funcs::pick_safe_adjacent_tile(), pos(), Creature::remove_effect(), rng(), set_healthy_mod(), set_thirst(), stomach, throws_up, calendar::turn, and wake_up().

Referenced by activate_mutation(), addict_effect(), iuse::artifact(), iuse::blech(), iuse::dig(), eat(), eff_fun_hallu(), eff_fun_hot(), eff_fun_rat(), hardcoded_effects(), marloss_common(), iuse::mycus(), process_effects_internal(), process_one_effect(), iuse::sewage(), suffer_feral_kill_withdrawl(), suffer_from_radiation(), suffer_while_awake(), try_reject_mutagen(), avatar::vomit(), and spell_effect::vomit().

◆ wait_effects()

void Character::wait_effects ( )

Definition at line 1526 of file character.cpp.

1527{
1528 if( has_effect( effect_downed ) ) {
1529 try_remove_downed( *this );
1530 return;
1531 }
1532 if( has_effect( effect_beartrap ) ) {
1533 try_remove_bear_trap( *this );
1534 return;
1535 }
1536 if( has_effect( effect_lightsnare ) ) {
1537 try_remove_lightsnare( *this );
1538 return;
1539 }
1540 if( has_effect( effect_heavysnare ) ) {
1541 try_remove_heavysnare( *this );
1542 return;
1543 }
1544 if( has_effect( effect_webbed ) ) {
1545 try_remove_webs( *this );
1546 return;
1547 }
1548 if( has_effect( effect_grabbed ) ) {
1549 try_remove_grab( *this );
1550 return;
1551 }
1552}

References effect_beartrap, effect_downed, effect_grabbed, effect_heavysnare, effect_lightsnare, effect_webbed, Creature::has_effect(), try_remove_bear_trap(), try_remove_downed(), try_remove_grab(), try_remove_heavysnare(), try_remove_lightsnare(), and try_remove_webs().

Referenced by character_funcs::do_pause().

◆ wake_up()

void Character::wake_up ( )

Removes "sleep" and "lying_down".

Definition at line 7576 of file character.cpp.

7577{
7581 if( has_effect( effect_sleep ) ) {
7582 g->events().send<event_type::character_wakes_up>( getID() );
7584 // Wake up might be called more than once per turn, but we only need to recalc after removing sleep
7586 }
7587}
static const efftype_id effect_slept_through_alarm("slept_through_alarm")
static const efftype_id effect_alarm_clock("alarm_clock")
@ character_wakes_up

References character_wakes_up, effect_alarm_clock, effect_lying_down, effect_sleep, effect_slept_through_alarm, g, getID(), Creature::has_effect(), recalc_sight_limits(), and Creature::remove_effect().

Referenced by hardcoded_effects(), on_hurt(), sounds::process_sound_markers(), react_to_felt_pain(), Creature::remove_effect(), suffer_feral_kill_withdrawl(), suffer_from_asthma(), suffer_from_sunburn(), update_bodytemp(), vomit(), and avatar::wake_up().

◆ warmth()

std::map< bodypart_id, int > Character::warmth ( const std::map< bodypart_id, std::vector< const item * > > &  clothing_map) const

Returns warmth provided by armor, etc.

Definition at line 9374 of file character.cpp.

9376{
9377 std::map<bodypart_id, int> ret;
9378 for( const bodypart_id &bp : get_all_body_parts() ) {
9379 ret.emplace( bp, 0 );
9380 }
9381
9382 for( const std::pair<const bodypart_id, std::vector<const item *>> &on_bp : clothing_map ) {
9383 const bodypart_id &bp = on_bp.first;
9384 for( const item *it : on_bp.second ) {
9385 double warmth = it->get_warmth();
9386 // Warmth reduced linearly with wetness
9387 const auto &materials = it->made_of();
9388 float max_wet_resistance = std::accumulate( materials.begin(), materials.end(), 0.0f,
9389 []( float best, const material_id & mat ) {
9390 return std::max( best, mat->warmth_when_wet() );
9391 } );
9392 float wet_mult = 1.0f - max_wet_resistance * body_wetness[bp->token] / drench_capacity[bp->token];
9393 ret[bp] += warmth * wet_mult;
9394 }
9395 ret[bp] += get_effect_int( effect_heating_bionic, bp->token );
9396 }
9397 return ret;
9398}
static const efftype_id effect_heating_bionic("heating_bionic")
int get_warmth() const
Returns the warmth value that this item has when worn.
Definition: item.cpp:5943

References body_wetness, drench_capacity, effect_heating_bionic, Creature::get_all_body_parts(), Creature::get_effect_int(), item::get_warmth(), item::made_of(), and cata::hash64_detail::ret.

Referenced by weather_effect::wet_player().

◆ wear_item()

std::optional< std::list< item >::iterator > Character::wear_item ( const item to_wear,
bool  interactive = true 
)

Wear a copy of specified item.

Parameters
to_wearItem to wear
interactiveIf set, won't alert the player or drain moves on completion
Returns
nullopt on fail, pointer to newly worn item on success.

Definition at line 2128 of file character.cpp.

2129{
2130 const auto ret = can_wear( to_wear );
2131 if( !ret.success() ) {
2132 if( interactive ) {
2133 add_msg_if_player( m_info, "%s", ret.c_str() );
2134 }
2135 return std::nullopt;
2136 }
2137
2138 const bool was_deaf = is_deaf();
2139 const bool supertinymouse = get_size() == MS_TINY;
2140 last_item = to_wear.typeId();
2141
2142 std::list<item>::iterator position = position_to_wear_new_item( to_wear );
2143 std::list<item>::iterator new_item_it = worn.insert( position, to_wear );
2144
2145 if( interactive ) {
2147 _( "You put on your %s." ),
2148 _( "<npcname> puts on their %s." ),
2149 to_wear.tname() );
2150 moves -= item_wear_cost( to_wear );
2151
2152 for( const body_part bp : all_body_parts ) {
2153 if( to_wear.covers( bp ) && encumb( bp ) >= 40 ) {
2155 bp == bp_eyes ?
2156 _( "Your %s are very encumbered! %s" ) : _( "Your %s is very encumbered! %s" ),
2157 body_part_name( bp ), encumb_text( bp ) );
2158 }
2159 }
2160 if( !was_deaf && is_deaf() ) {
2161 add_msg_if_player( m_info, _( "You're deafened!" ) );
2162 }
2163 if( supertinymouse && !to_wear.has_flag( flag_UNDERSIZE ) ) {
2165 _( "This %s is too big to wear comfortably! Maybe it could be refitted." ),
2166 to_wear.tname() );
2167 } else if( !supertinymouse && to_wear.has_flag( flag_UNDERSIZE ) ) {
2169 _( "This %s is too small to wear comfortably! Maybe it could be refitted." ),
2170 to_wear.tname() );
2171 }
2172 } else {
2173 add_msg_if_npc( _( "<npcname> puts on their %s." ), to_wear.tname() );
2174 }
2175
2176 new_item_it->on_wear( *this );
2177
2178 inv.update_invlet( *new_item_it );
2179 inv.update_cache_with_item( *new_item_it );
2180
2183
2184 return new_item_it;
2185}
std::string encumb_text(body_part bp)
Returns the matching encumbrance text for a given body_part token.
Definition: bodypart.cpp:360
static const std::string flag_UNDERSIZE("UNDERSIZE")
void update_invlet(item &it, bool assign_invlet=true)
Definition: inventory.cpp:1217
void update_cache_with_item(item &newit)
Definition: inventory.cpp:253

References _, Creature::add_msg_if_npc(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), all_body_parts, body_part_name(), bp_eyes, can_wear(), item::covers(), encumb(), encumb_text(), flag_UNDERSIZE(), get_size(), item::has_flag(), inv, is_deaf(), item_wear_cost(), last_item, m_info, m_warning, Creature::moves, MS_TINY, position, position_to_wear_new_item(), recalc_sight_limits(), reset_encumbrance(), cata::hash64_detail::ret, item::tname(), item::typeId(), inventory::update_cache_with_item(), inventory::update_invlet(), and worn.

Referenced by activity_on_turn_wear(), iexamine::autodoc(), avatar::create(), dispose_item(), pick_one_up(), spell_effect::spawn_ethereal_item(), standard_npc::standard_npc(), npc::stow_item(), avatar_funcs::use_item(), npc::wear_if_wanted(), and wear_possessed().

◆ wear_possessed()

std::optional< std::list< item >::iterator > Character::wear_possessed ( item to_wear,
bool  interactive = true 
)

Wear specified item.

Item must be in characters possession (wielded or stored).

Parameters
to_wearItem to wear
interactiveIf set, won't alert the player or drain moves on completion
Returns
nullopt on fail, pointer to newly worn item on success

Definition at line 2976 of file character.cpp.

2977{
2978 if( is_worn( to_wear ) ) {
2979 if( interactive ) {
2981 _( "You are already wearing that." ),
2982 _( "<npcname> is already wearing that." )
2983 );
2984 }
2985 return std::nullopt;
2986 }
2987 if( to_wear.is_null() ) {
2988 if( interactive ) {
2990 _( "You don't have that item." ),
2991 _( "<npcname> doesn't have that item." ) );
2992 }
2993 return std::nullopt;
2994 }
2995
2996 bool was_weapon;
2997 item to_wear_copy( to_wear );
2998 item &weapon = primary_weapon();
2999 if( &to_wear == &weapon ) {
3000 weapon = item();
3001 was_weapon = true;
3002 } else {
3003 inv.remove_item( &to_wear );
3004 inv.restack( *this->as_player() );
3005 was_weapon = false;
3006 }
3007
3008 auto result = wear_item( to_wear_copy, interactive );
3009 if( !result ) {
3010 if( was_weapon ) {
3011 weapon = to_wear_copy;
3012 } else {
3013 inv.add_item( to_wear_copy, true );
3014 }
3015 return std::nullopt;
3016 }
3017
3018 return result;
3019}

References _, inventory::add_item(), Creature::add_msg_player_or_npc(), Creature::as_player(), inv, item::is_null(), is_worn(), m_info, primary_weapon(), inventory::remove_item(), inventory::restack(), and wear_item().

Referenced by examine_item_menu::run(), show_armor_layers_ui(), and wear().

◆ wearing_something_on()

bool Character::wearing_something_on ( const bodypart_id bp) const

Returns true if the character is wearing something on the entered body part.

Definition at line 8861 of file character.cpp.

8862{
8863 for( auto &i : worn ) {
8864 if( i.covers( bp->token ) ) {
8865 return true;
8866 }
8867 }
8868 return false;
8869}

References worn.

Referenced by armwear_factor(), can_drink_nectar(), can_wear(), iexamine::chainfence(), footwear_factor(), on_hit(), reset_stats(), suffer_from_sunburn(), and suffer_in_sunlight().

◆ weight_capacity()

units::mass Character::weight_capacity ( ) const
overridevirtual
Strength increases carrying capacity

Reimplemented from Creature.

Definition at line 2626 of file character.cpp.

2627{
2629 // Infinite enough
2630 return units::mass_max;
2631 }
2632 // Get base capacity from creature,
2633 // then apply player-only mutation and trait effects.
2635 /** @EFFECT_STR increases carrying capacity */
2636 ret += get_str() * 4_kilogram;
2637 ret *= mutation_value( "weight_capacity_modifier" );
2638
2639 units::mass worn_weight_bonus = 0_gram;
2640 for( const item &it : worn ) {
2641 ret *= it.get_weight_capacity_modifier();
2642 worn_weight_bonus += it.get_weight_capacity_bonus();
2643 }
2644
2645 units::mass bio_weight_bonus = 0_gram;
2646 for( const bionic_id &bid : get_bionics() ) {
2647 ret *= bid->weight_capacity_modifier;
2648 bio_weight_bonus += bid->weight_capacity_bonus;
2649 }
2650
2651 ret += bio_weight_bonus + worn_weight_bonus;
2652
2654 ret += 22500_gram;
2655 }
2656
2657 if( ret < 0_gram ) {
2658 ret = 0_gram;
2659 }
2660 if( is_mounted() ) {
2661 auto *mons = mounted_creature.get();
2662 // the mech has an effective strength for other purposes, like hitting.
2663 // but for lifting, its effective strength is even higher, due to its sturdy construction, leverage,
2664 // and being built entirely for that purpose with hydraulics etc.
2665 ret = mons->mech_str_addition() == 0 ? ret : ( mons->mech_str_addition() + 10 ) * 4_kilogram;
2666 }
2667 return ret;
2668}
virtual units::mass weight_capacity() const
Definition: creature.cpp:1833
@ AEP_CARRY_MORE
Definition: enums.h:118

References AEP_CARRY_MORE, get_bionics(), get_str(), has_artifact_with(), has_trait(), is_mounted(), units::mass_max, mounted_creature, mutation_value(), cata::hash64_detail::ret, trait_DEBUG_STORAGE, Creature::weight_capacity(), and worn.

Referenced by activate_bionic(), are_requirements_nearby(), burn_move_stamina(), can_pick_weight(), carry_weight_string(), pickup::cost_to_move_item(), overmap_ui::display(), pickup::do_pickup(), draw_speed_tab(), draw_stats_info(), draw_weightvolume_labels(), npc::drop_items(), fetch_activity(), find_best_bench(), npc::find_item(), inventory_selector::get_raw_stats(), inventory_drop_selector::get_raw_stats(), iexamine::ledge(), npc_pickup_from_stack(), trading_window::perform_trade(), recalc_speed_bonus(), set_stats(), suffer_while_awake(), and weight_carried_reduced_by().

◆ weight_carried()

◆ weight_carried_reduced_by()

units::mass Character::weight_carried_reduced_by ( const excluded_stacks without) const

Definition at line 2568 of file character.cpp.

2569{
2570 const std::map<const item *, int> empty;
2571
2572 // Worn items
2573 units::mass ret = 0_gram;
2574 for( auto &i : worn ) {
2575 if( !without.count( &i ) ) {
2576 ret += i.weight();
2577 }
2578 }
2579
2580 // Items in inventory
2581 ret += inv.weight_without( without );
2582
2583 // Wielded item
2584 units::mass weaponweight = 0_gram;
2585 const item &weapon = primary_weapon();
2586 auto weapon_it = without.find( &weapon );
2587 if( weapon_it == without.end() ) {
2588 weaponweight = weapon.weight();
2589 } else {
2590 int subtract_count = ( *weapon_it ).second;
2591 if( weapon.count_by_charges() ) {
2592 item copy = weapon;
2593 copy.charges -= subtract_count;
2594 if( copy.charges < 0 ) {
2595 debugmsg( "Trying to remove more charges than the wielded item has" );
2596 copy.charges = 0;
2597 }
2598 weaponweight = copy.weight();
2599 } else if( subtract_count > 1 ) {
2600 debugmsg( "Trying to remove more than one wielded item" );
2601 }
2602 }
2603 // Exclude wielded item if using lifting tool
2604 if( weaponweight + ret > weight_capacity() ) {
2605 const float liftrequirement = std::ceil( units::to_gram<float>( weaponweight ) /
2606 units::to_gram<float>( TOOL_LIFT_FACTOR ) );
2607 if( g->new_game || best_nearby_lifting_assist() < liftrequirement ) {
2608 ret += weaponweight;
2609 }
2610 } else {
2611 ret += weaponweight;
2612 }
2613
2614 return ret;
2615}
units::mass weight_without(const excluded_stacks &without) const
Definition: inventory.cpp:1042
#define TOOL_LIFT_FACTOR

References best_nearby_lifting_assist(), item::charges, item::count_by_charges(), debugmsg, g, inv, primary_weapon(), cata::hash64_detail::ret, TOOL_LIFT_FACTOR, item::weight(), weight_capacity(), inventory::weight_without(), and worn.

Referenced by inventory_drop_selector::get_raw_stats(), and weight_carried().

◆ wield()

virtual bool Character::wield ( item target)
pure virtual

Removes currently wielded item (if any) and replaces it with the target item.

Parameters
targetreplacement item to wield or null item to remove existing weapon without replacing it
Returns
whether both removal and replacement were successful (they are performed atomically)

Implemented in npc, and avatar.

Referenced by handle_melee_wear(), mount_creature(), perform_technique(), pick_one_up(), and mattack::riotbot().

◆ wielded_items() [1/2]

std::vector< item * > Character::wielded_items ( )

Returns all equipped items that require a limb to be held.

Definition at line 185 of file melee.cpp.

186{
187 if( get_body().find( body_part_arm_r ) == get_body().end() ) {
188 return {};
189 }
190 const bodypart &right_arm = get_part( body_part_arm_r );
191 const auto wielded = right_arm.wielding.wielded;
192 if( wielded != nullptr && !wielded->is_null() ) {
193 return {& *wielded};
194 }
195
196 return {};
197}

References body_part_arm_r, detail::find(), Creature::get_body(), Creature::get_part(), wield_status::wielded, and bodypart::wielding.

Referenced by player::get_eligible_containers_for_crafting(), has_artifact_with(), npc_trading::init_selling(), avatar_action::plthrow(), avatar_action::reload_weapon(), avatar_action::reload_wielded(), and wielded_items().

◆ wielded_items() [2/2]

std::vector< const item * > Character::wielded_items ( ) const

Definition at line 199 of file melee.cpp.

200{
201 const auto nonconst_ret = const_cast<Character *>( this )->wielded_items();
202 return std::vector<const item *>( nonconst_ret.begin(), nonconst_ret.end() );
203}

References wielded_items().

◆ will_eat()

ret_val< edible_rating > Character::will_eat ( const item food,
bool  interactive = false 
) const

Same as can_eat, but takes consequences into account.

Asks about them if

Parameters
interactiveis true, refuses otherwise.

Definition at line 732 of file consumption.cpp.

733{
734 const auto ret = can_eat( food );
735 if( !ret.success() ) {
736 if( interactive ) {
737 add_msg_if_player( m_info, "%s", ret.c_str() );
738 }
739 return ret;
740 }
741
742 std::vector<ret_val<edible_rating>> consequences;
743 const auto add_consequence = [&consequences]( const std::string & msg, edible_rating code ) {
744 consequences.emplace_back( ret_val<edible_rating>::make_failure( code, msg ) );
745 };
746
747 const bool saprophage = has_trait( trait_SAPROPHAGE );
748 const auto &comest = food.get_comestible();
749
750 if( food.rotten() ) {
751 const bool saprovore = has_trait( trait_SAPROVORE );
752 if( !saprophage && !saprovore && !has_bionic( bio_digestion ) ) {
753 add_consequence( _( "This is rotten and smells awful!" ), edible_rating::rotten );
754 }
755 }
756
757 const bool carnivore = has_trait( trait_CARNIVORE );
758 if( food.has_flag( flag_CANNIBALISM ) && !has_trait_flag( "CANNIBAL" ) ) {
759 add_consequence( _( "The thought of eating human flesh makes you feel sick." ),
761 }
762
763 const bool edible = comest->comesttype == comesttype_FOOD || food.has_flag( flag_USE_EAT_VERB );
764
765 int food_kcal = compute_effective_nutrients( food ).kcal;
766 if( food_kcal > 0 && has_effect( effect_nausea ) ) {
767 add_consequence( _( "You still feel nauseous and will probably puke it all up again." ),
769 }
770
771 if( ( food_kcal > 0 || comest->quench > 0 ) && has_effect( effect_bloated )
772 && !food.has_flag( flag_NO_BLOAT ) ) {
773 add_consequence( _( "You're full and will vomit if you try to consume anything." ),
775 }
776
777 if( ( allergy_type( food ) != MORALE_NULL ) || ( carnivore && food.has_flag( flag_ALLERGEN_JUNK ) &&
778 !food.has_flag( flag_CARNIVORE_OK ) ) ) {
779 add_consequence( _( "Your stomach won't be happy (allergy)." ), edible_rating::allergy );
780 }
781
782 if( saprophage && edible && food.rotten() && !food.has_flag( flag_FERTILIZER ) ) {
783 // Note: We're allowing all non-solid "food". This includes drugs
784 // Hard-coding fertilizer for now - should be a separate flag later
785 //~ No, we don't eat "rotten" food. We eat properly aged food, like a normal person.
786 //~ Semantic difference, but greatly facilitates people being proud of their character.
787 add_consequence( _( "Your stomach won't be happy (not rotten enough)." ),
789 }
790
791 if( !food.has_infinite_charges() &&
792 ( ( food_kcal > 0 &&
793 get_stored_kcal() + stomach.get_calories() + food_kcal
794 > max_stored_kcal() ) ||
795 ( comest->quench > 0 && get_thirst() < comest->quench ) ) ) {
796 add_consequence( _( "You're full already and the excess food will be wasted." ),
798 }
799
800 if( !consequences.empty() ) {
801 if( !interactive ) {
802 return consequences.front();
803 }
804 std::string req;
805 for( const auto &elem : consequences ) {
806 req += elem.str() + "\n";
807 }
808
809 const bool eat_verb = food.has_flag( flag_USE_EAT_VERB );
810 std::string food_tname = food.tname();
811 const nc_color food_color = food.color_in_inventory();
812 if( eat_verb || comest->comesttype == comesttype_FOOD ) {
813 req += string_format( _( "Eat your %s anyway?" ), colorize( food_tname, food_color ) );
814 } else if( !eat_verb && comest->comesttype == comesttype_DRINK ) {
815 req += string_format( _( "Drink your %s anyway?" ), colorize( food_tname, food_color ) );
816 } else {
817 req += string_format( _( "Consume your %s anyway?" ), colorize( food_tname, food_color ) );
818 }
819
820 if( !query_yn( req ) ) {
821 return consequences.front();
822 }
823 }
824 // All checks ended, it's edible (or we're pretending it is)
826}
edible_rating
Definition: character.h:164
bool has_infinite_charges() const
Definition: item.cpp:9990
The class represents a composite return value of an arbitrary function (result).
Definition: ret_val.h:21
static const std::string flag_FERTILIZER("FERTILIZER")
static const efftype_id effect_nausea("nausea")

References _, Creature::add_msg_if_player(), allergy, allergy_type(), allergy_weak, bio_digestion, bloated, can_eat(), cannibalism, item::color_in_inventory(), colorize(), comesttype_DRINK(), comesttype_FOOD(), compute_effective_nutrients(), edible, effect_bloated, effect_nausea, flag_ALLERGEN_JUNK(), flag_CANNIBALISM(), flag_CARNIVORE_OK(), flag_FERTILIZER(), flag_NO_BLOAT(), flag_USE_EAT_VERB(), stomach_contents::get_calories(), item::get_comestible(), get_stored_kcal(), get_thirst(), has_bionic(), Creature::has_effect(), item::has_flag(), item::has_infinite_charges(), has_trait(), has_trait_flag(), nutrients::kcal, m_info, ret_val< T >::make_success(), max_stored_kcal(), MORALE_NULL, nausea, query_yn(), cata::hash64_detail::ret, rotten, item::rotten(), stomach, string_format(), item::tname(), too_full, trait_CARNIVORE, trait_SAPROPHAGE, and trait_SAPROVORE.

Referenced by item::color_in_inventory(), npc::consume_food(), eat(), find_auto_consume(), examine_item_menu::rate_action_eat(), and npc::value().

◆ worn_position_to_index()

static int Character::worn_position_to_index ( int  position)
inlinestatic

Definition at line 1094 of file character.h.

1094 {
1095 return -2 - position;
1096 }

References position.

Referenced by advanced_inventory::action_examine(), get_item_position(), i_at(), i_rem(), and avatar_action::wield().

◆ worn_with_flag()

Member Data Documentation

◆ _skills

◆ activity

player_activity Character::activity

Definition at line 1578 of file character.h.

Referenced by activate_mutation(), activity_on_turn_move_loot(), assign_activity(), assign_stashed_activity(), iexamine::autodoc(), activity_handlers::build_do_turn(), iuse::burrow(), game::butcher(), butcher_corpse_activity(), character_effects::calc_focus_equilibrium(), cancel_activity(), game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), check_outbounds_activity(), iuse::chop_logs(), chop_plank_activity(), iuse::chop_tree(), chop_tree_activity(), iuse::clear_rubble(), complete_construction(), veh_interact::complete_vehicle(), construction_activity(), iuse::craft(), iuse::cut_log_into_planks(), veh_interact::do_main_loop(), npc::do_player_activity(), npc::do_pulp(), avatar::do_read(), game::do_turn(), player_activity::do_turn(), pickup_activity_actor::do_turn(), npc::drop(), eff_fun_bleed(), fall_asleep(), fetch_activity(), iuse::fill_pit(), activity_handlers::find_mount_do_turn(), npc::finish_read(), iuse::fishing_rod(), game::forced_door_closing(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_handler(), player_activity::get_progress_message(), talk_function::give_aid(), talk_function::give_all_aid(), avatar_funcs::gunmod_add(), iuse::hacksaw(), iuse::hand_crank(), game::handle_key_blocking_activity(), hardcoded_effects(), has_activity(), npc::has_player_activity(), in_sleep_state(), install_bionics(), vehicle::interact_with(), inv_internal(), iuse::jackhammer(), load(), npc::load(), iuse::makemound(), monexamine::milk_source(), mine_activity(), npc::move(), map::move_vehicle(), npc::on_load(), iuse::oxytorch(), perform_zone_activity_turn(), iuse::pickaxe(), game::place_player(), monexamine::play_with(), iuse::portable_game(), game::process_activity(), sounds::process_sound_markers(), process_turn(), game::process_voluntary_act_interrupt(), avatar::read(), npc::reboot(), avatar_action::reload(), DefaultRemovePartHandler::removed(), activity_handlers::repair_item_finish(), resume_backlog_activity(), npc::revert_after_activity(), iexamine::rubble(), iexamine::safe(), conditional_t< T >::set_has_activity(), npc::set_mission(), monexamine::shear_animal(), show_armor_layers_ui(), iexamine::shrub_wildveggies(), smash(), player::start_craft(), store(), npc::talk_to_u(), avatar_funcs::toolmod_add(), iexamine::trap(), try_start_hacking(), uninstall_bionic(), update_needs(), pick_lock_actor::use(), firestarter_actor::use(), enzlave_actor::use(), ammobelt_actor::use(), repair_item_actor::use(), heal_actor::use(), cast_spell_actor::use(), heal_actor::use_healing_item(), vehicle_activity(), and iuse::vibe().

◆ activity_vehicle_part_index

◆ addictions

◆ ammo_location

item_location Character::ammo_location

Definition at line 1602 of file character.h.

◆ anchor

safe_reference_anchor Character::anchor
private

Definition at line 2281 of file character.h.

Referenced by get_safe_reference().

◆ auto_move_route

std::vector<tripoint> Character::auto_move_route
private

◆ autolearn_skills_stamp

pimpl<SkillLevelMap> Character::autolearn_skills_stamp
mutableprotected

Stamp of character skills.

learned_recipes are valid only with this set of skills.

Definition at line 2177 of file character.h.

Referenced by get_learned_recipes(), load(), and store().

◆ backlog

◆ bio_soporific_powered_at_last_sleep_check

bool Character::bio_soporific_powered_at_last_sleep_check = false

Definition at line 2159 of file character.h.

Referenced by character_funcs::roll_can_sleep(), and avatar_funcs::try_to_sleep().

◆ blocks_left

int Character::blocks_left = 0

Definition at line 568 of file character.h.

Referenced by block_hit(), player::player(), and process_turn().

◆ body_wetness

◆ cached_crafting_inventory

inventory Character::cached_crafting_inventory
private

Definition at line 2277 of file character.h.

Referenced by crafting_inventory().

◆ cached_moves

int Character::cached_moves = 0
private

Definition at line 2275 of file character.h.

Referenced by crafting_inventory().

◆ cached_mutations

std::vector<const mutation_branch *> Character::cached_mutations
protected

◆ cached_position

tripoint Character::cached_position
private

Definition at line 2276 of file character.h.

Referenced by crafting_inventory(), and invalidate_crafting_inventory().

◆ cached_time

time_point Character::cached_time

Definition at line 1605 of file character.h.

Referenced by crafting_inventory(), and invalidate_crafting_inventory().

◆ camps

std::set<tripoint_abs_omt> Character::camps

◆ cash

int Character::cash = 0

◆ check_encumbrance

bool Character::check_encumbrance = true
private

◆ consumption_history

pimpl<consumption_history_t> Character::consumption_history

Definition at line 1591 of file character.h.

Referenced by eat(), fun_for(), load(), and store().

◆ controlling_vehicle

◆ custom_profession

std::string Character::custom_profession

◆ damage_bandaged

std::array<int, num_hp_parts> Character::damage_bandaged

Definition at line 1570 of file character.h.

Referenced by heal_actor::finish_using(), load(), regen(), and player::store().

◆ damage_disinfected

std::array<int, num_hp_parts> Character::damage_disinfected

Definition at line 1570 of file character.h.

Referenced by iexamine::autodoc(), heal_actor::finish_using(), load(), regen(), and player::store().

◆ death_drops

bool Character::death_drops = true

Definition at line 252 of file character.h.

Referenced by npc::npc(), place_corpse(), and player::player().

◆ destination_activity

player_activity Character::destination_activity
private

◆ destination_point

◆ dex_bonus

int Character::dex_bonus = 0
protected

◆ dex_cur

◆ dex_max

◆ dodges_left

int Character::dodges_left = 0

Definition at line 569 of file character.h.

Referenced by get_dodge(), game::is_game_over(), on_dodge(), player::player(), and process_turn().

◆ drench_capacity

std::array<int, num_bp> Character::drench_capacity

◆ enchantment_cache

◆ encumbrance_cache

pimpl<char_encumbrance_data> Character::encumbrance_cache
protected

Definition at line 2149 of file character.h.

Referenced by encumb(), extraEncumbrance(), get_encumbrance(), and reset_encumbrance().

◆ fac_id

◆ faction_api_version

int Character::faction_api_version = 2
protected

◆ fatigue

int Character::fatigue = 0
private

◆ fleshy

const std::vector< material_id > Character::fleshy = { material_id( "flesh" ), material_id( "hflesh" ) }
static

Definition at line 786 of file character.h.

Referenced by made_of(), and made_of_any().

◆ focus_pool

◆ follower_ids

std::set<character_id> Character::follower_ids

Definition at line 1600 of file character.h.

◆ frostbite_timer

std::array<int, num_bp> Character::frostbite_timer

Definition at line 2293 of file character.h.

Referenced by load(), store(), and update_bodytemp().

◆ hauling

bool Character::hauling = false

Definition at line 1574 of file character.h.

Referenced by is_hauling(), player::player(), start_hauling(), and stop_hauling().

◆ healed_total

std::array<int, num_hp_parts> Character::healed_total

Definition at line 1779 of file character.h.

Referenced by healed_bp(), load(), and store().

◆ healthy

int Character::healthy = 0
protected

How healthy the character is.

Definition at line 2138 of file character.h.

Referenced by get_healthy(), load(), mod_healthy(), set_healthy(), and store().

◆ healthy_mod

int Character::healthy_mod = 0
protected

Definition at line 2139 of file character.h.

Referenced by get_healthy_mod(), load(), mod_healthy_mod(), set_healthy_mod(), and store().

◆ id

◆ in_vehicle

◆ init_age

int Character::init_age = 25
protected

age in years at character creation

Definition at line 2142 of file character.h.

Referenced by age(), base_age(), load(), mod_base_age(), avatar::randomize(), reset_chargen_attributes(), set_base_age(), and store().

◆ init_height

int Character::init_height = 175
protected

height at character creation

Definition at line 2144 of file character.h.

Referenced by base_height(), height(), load(), mod_base_height(), avatar::randomize(), reset_chargen_attributes(), set_base_height(), and store().

◆ int_bonus

int Character::int_bonus = 0
protected

◆ int_cur

◆ int_max

◆ inv

inventory Character::inv

Definition at line 1581 of file character.h.

Referenced by inventory_selector::add_character_items(), advanced_inventory_pane::add_items_from_area(), allocated_invlets(), npc::alt_attack(), autoclave_internal(), autodoc_internal(), behavior::character_oracle_t::can_make_fire(), can_pick_volume(), player::can_start_craft(), iuse_transform::can_use(), behavior::character_oracle_t::can_wear_warmer_clothes(), debug_menu::character_edit_menu(), game_menus::inv::common(), game_menus::inv::compare(), complete_craft(), consume(), npc::consume_cbm_items(), npc::consume_food(), convert_to_items(), crafting_inventory(), avatar::create(), npc::decide_needs(), die(), dispose_item(), npc::dispose_item(), drop_invalid_inventory(), npc::drop_items(), findBestGasDiscount(), player::get_eligible_containers_for_crafting(), item::get_encumber(), get_item_position(), item::get_remaining_capacity_for_liquid(), get_weight(), behavior::character_oracle_t::has_food(), npc::has_painkiller(), behavior::character_oracle_t::has_water(), npc::heal_self(), i_add(), i_add_or_drop(), i_at(), i_rem(), tutorial_game::init(), npc_trading::init_buying(), npc_trading::init_selling(), inv_dump(), inv_internal(), irradiate(), leak_level(), avatar::load(), load(), npc::mug_player(), game_menus::inv::multidrop(), iexamine::pay_gas(), pour_into(), process_items(), iuse::radiocar(), npc::randomize(), game_menus::inv::reassign_letter(), item::reload(), pickup::reorder_for_dropping(), player::select_requirements(), set_item_inventory(), npc::shop_restock(), show_armor_layers_ui(), iuse::smoking(), starting_inv(), avatar::store(), player::store(), game_menus::inv::swap_letters(), avatar_action::swim(), takeoff(), character_funcs::try_wield_contents(), unwield(), npc::update_worst_item_value(), use_amount(), npc::use_painkiller(), volume_carried(), volume_carried_reduced_by(), wash_items(), wear_item(), wear_possessed(), weight_carried_reduced_by(), avatar::wield(), and memorial_logger::write().

◆ known_traps

trap_map Character::known_traps
protected

Definition at line 2148 of file character.h.

Referenced by add_known_trap(), knows_trap(), load(), and store().

◆ last_climate_control_ret

bool Character::last_climate_control_ret = false

Definition at line 2298 of file character.h.

Referenced by in_climate_control(), and game::start_game().

◆ last_item

◆ last_sleep_check

time_point Character::last_sleep_check = calendar::turn_zero

Definition at line 2158 of file character.h.

Referenced by player::load(), character_funcs::roll_can_sleep(), and player::store().

◆ learned_recipes

pimpl<recipe_subset> Character::learned_recipes
mutableprotected

Subset of learned recipes.

Needs to be mutable for lazy initialization.

Definition at line 2179 of file character.h.

Referenced by avatar::create(), get_learned_recipes(), learn_recipe(), load(), and store().

◆ magic

◆ male

◆ martial_arts_data

◆ max_power_level

◆ melee_miss_reasons

struct weighted_int_list< std::string > Character::melee_miss_reasons
private

Definition at line 2273 of file character.h.

Referenced by add_miss_reason(), clear_miss_reasons(), and get_miss_reason().

◆ morale

◆ mounted_creature

◆ mounted_creature_id

int Character::mounted_creature_id = 0

Definition at line 1619 of file character.h.

Referenced by load().

◆ move_mode

◆ mut_drench

std::array<std::array<int, NUM_WATER_TOLERANCE>, num_bp> Character::mut_drench
protected

Definition at line 860 of file character.h.

Referenced by apply_wetness_morale(), and drench_mut_calc().

◆ mutation_category_level

std::map<std::string, int> Character::mutation_category_level

◆ my_bionics

◆ my_fac

◆ my_mutations

mutation_collection Character::my_mutations

Traits / mutations of the character.

Key is the mutation id (it's also a valid key into mutation_data), the value describes the status of the mutation. If there is not entry for a mutation, the character does not have it. If the map contains the entry, the character has the mutation.

Definition at line 2157 of file character.h.

Referenced by activate_mutation(), active_light(), clear_mutations(), avatar::create(), deactivate_mutation(), get_mutations(), get_overlay_ids(), has_active_mutation(), has_opposite_trait(), has_trait(), load(), mutation_effect(), mutation_spend_resources(), rebuild_mutation_cache(), set_mutation(), detail::show_mutations_ui_internal(), store(), suffer(), switch_mutations(), toggle_trait(), and unset_mutation().

◆ my_traits

std::unordered_set<trait_id> Character::my_traits
protected

Contains mutation ids of the base traits.

Definition at line 2164 of file character.h.

Referenced by clear_mutations(), get_base_traits(), has_base_trait(), load(), store(), and toggle_trait().

◆ name

std::string Character::name

Definition at line 1566 of file character.h.

Referenced by assign_activity(), vehicle::automatic_fire_turret(), bionics_install_failure(), map::board_vehicle(), body_window(), butcher_corpse_activity(), butchery_drops_harvest(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), talk_function::buy_haircut(), talk_function::buy_shave(), veh_interact::calc_overview(), can_wear(), enchantment::cast_enchantment_spell(), debug_menu::character_edit_menu(), avatar::character_to_template(), activity_handlers::chop_logs_finish(), game::cleanup_at_end(), veh_interact::complete_vehicle(), target_ui::confirm_non_enemy_target(), npc::consume_food(), consume_item(), avatar::create(), mission_end::deposit_box(), item_location::impl::item_on_person::describe(), diary::diary(), npc::die(), disp_name(), npc::do_reload(), overmap_ui::draw_ascii(), draw_tip(), npc::drop_items(), dialogue::dynamic_line(), talk_function::end_conversation(), enumerate_unmet_requirements(), npc::execute_action(), extended_description(), npc::faction_display(), fetch_activity(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_plant(), basecamp::finish_return(), ranged::fire_gun(), overmapbuffer::fix_npcs(), talk_function::flee(), talk_function::forage_return(), game::forced_door_closing(), npc::form_opinion(), iuse::geiger(), generic_multi_activity_locations(), get_name(), avatar::get_save_id(), vehicle::get_targeting_npc(), talk_function::give_aid(), talk_function::give_all_aid(), talk_function::give_equipment(), npc::go_to_omt_destination(), npc::handle_sound(), hardcoded_effects(), iexamine::harvest_plant(), healing_rate(), talk_function::hostile(), tutorial_game::init(), talk_function::insult_combat(), activity_handlers::jackhammer_finish(), talk_function::labor_return(), talk_function::leave(), load(), npc_template::load(), game::load(), npc::load_npc_template(), make_fake_npc(), melee_attack(), talk_function::morale_chat_activity(), npc::move(), move_item(), npc::move_to(), npc::mug_player(), mutation_attacks(), game::npc_menu(), npc_temp_orders_menu(), npc_throw(), on_hit(), npc::on_load(), dialogue::opt(), perform_technique(), trading_window::perform_trade(), petfood(), pick_name(), npc::pick_up_item(), activity_handlers::pickaxe_finish(), place_corpse(), mission_start::place_dog(), mission_start::place_npc_software(), npc::print_info(), print_info(), avatar::randomize(), talk_function::remove_overseer(), reveal_target(), rod_fish(), game::save(), avatar::save_template(), npc::say(), npc::scan_new_items(), talk_function::scavenging_patrol_return(), talk_function::scavenging_raid_return(), npc::set_attitude(), set_description(), talk_function::set_npc_pickup(), talk_effect_fun_t::set_u_buy_item(), talk_effect_fun_t::set_u_buy_monster(), talk_effect_fun_t::set_u_sell_item(), npc::setpos(), short_description_parts(), show_armor_layers_ui(), show_photo_selection(), map::smash_trap(), standard_npc::standard_npc(), talk_function::start_mugging(), game_menus::inv::steal(), talk_function::stop_following(), talk_function::stop_guard(), store(), talk_function::stranger_neutral(), suffer_from_schizophrenia(), survive_random_encounter(), npc::talk_to_u(), tidy_activity(), npc::travel_overmap(), avatar_funcs::try_disarm_npc(), avatar_funcs::try_steal_from_npc(), update_time_fixed(), trading_window::update_win(), npc::warn_about(), main_menu::world_tab(), and memorial_logger::write().

◆ next_climate_control_check

time_point Character::next_climate_control_check

Definition at line 2297 of file character.h.

Referenced by in_climate_control(), and game::start_game().

◆ next_expected_position

std::optional<tripoint> Character::next_expected_position
private

◆ npc_ai_info_cache

std::array<double, npc_ai_info::num_npc_ai_info> Character::npc_ai_info_cache
mutableprivate

◆ nv_cached

bool Character::nv_cached = false

Definition at line 1571 of file character.h.

Referenced by action_taken(), has_nv(), player::player(), and reset_stats().

◆ nv_range

float Character::nv_range = 0
protected

Definition at line 2184 of file character.h.

Referenced by get_vision_threshold(), and recalc_sight_limits().

◆ omt_path

◆ overmap_time

std::unordered_map<point_abs_omt, time_duration> Character::overmap_time
protected

Amount of time the player has spent in each overmap tile.

Definition at line 2289 of file character.h.

Referenced by apply_persistent_morale(), load(), process_turn(), and store().

◆ oxygen

◆ path_settings

pimpl<pathfinding_settings> Character::path_settings
mutableprotected

Cache for pathfinding settings.

Most of it isn't changed too often, hence mutable.

Definition at line 2195 of file character.h.

Referenced by get_pathfinding_settings(), npc::get_pathfinding_settings(), avatar::grab(), and npc::npc().

◆ per_bonus

int Character::per_bonus = 0
protected

◆ per_cur

◆ per_max

◆ pkill

int Character::pkill = 0
private

◆ position

◆ power_level

units::energy Character::power_level
private

◆ prof

◆ radiation

int Character::radiation = 0
private

Definition at line 2266 of file character.h.

Referenced by get_rad(), load(), set_rad(), and store().

◆ reach_attacking

bool Character::reach_attacking = false

Definition at line 621 of file character.h.

Referenced by melee_attack(), and reach_attack().

◆ reactor_plut

int Character::reactor_plut = 0

Definition at line 1595 of file character.h.

Referenced by player::load(), and player::store().

◆ recoil

◆ scent

int Character::scent = 0

Definition at line 1586 of file character.h.

Referenced by process_turn().

◆ sight_max

int Character::sight_max = 0
protected

Definition at line 2185 of file character.h.

Referenced by player::player(), recalc_sight_limits(), sight_range(), and unimpaired_range().

◆ size_class

m_size Character::size_class = MS_MEDIUM
protected

Size class of character.

Definition at line 2146 of file character.h.

Referenced by get_size(), and recalculate_size().

◆ sleep_deprivation

int Character::sleep_deprivation = 0
private

◆ slow_rad

int Character::slow_rad = 0

Definition at line 1596 of file character.h.

Referenced by player::load(), and player::store().

◆ stamina

int Character::stamina = 0
private

Definition at line 2257 of file character.h.

Referenced by get_stamina(), load(), mod_stamina(), set_stamina(), and store().

◆ stashed_outbounds_activity

◆ stashed_outbounds_backlog

player_activity Character::stashed_outbounds_backlog

◆ stim

int Character::stim = 0
private

Definition at line 2263 of file character.h.

Referenced by get_stim(), load(), mod_stim(), set_stim(), and store().

◆ stomach

◆ stored_calories

int Character::stored_calories = 0
private

Needs (hunger, starvation, thirst, fatigue, etc.)

Definition at line 2254 of file character.h.

Referenced by get_hunger_description(), get_stored_kcal(), load(), mod_stored_kcal(), set_stored_kcal(), and store().

◆ str_bonus

int Character::str_bonus = 0
protected

Bonuses to stats, calculated each turn.

Definition at line 2132 of file character.h.

Referenced by get_str(), get_str_bonus(), load(), mod_str_bonus(), reset_bonuses(), set_str_bonus(), and store().

◆ str_cur

◆ str_max

◆ tank_plut

int Character::tank_plut = 0

Definition at line 1594 of file character.h.

Referenced by player::load(), and player::store().

◆ temp_conv

◆ temp_cur

◆ thirst

int Character::thirst = 0
private

Definition at line 2256 of file character.h.

Referenced by get_thirst(), get_thirst_description(), load(), mod_thirst(), set_thirst(), and store().

◆ time_died

time_point Character::time_died = calendar::before_time_starts
protected

Definition at line 2189 of file character.h.

Referenced by get_time_died(), and set_time_died().

◆ type_of_scent

scenttype_id Character::type_of_scent
private

Definition at line 2271 of file character.h.

Referenced by get_type_of_scent(), load(), set_type_of_scent(), and store().

◆ vision_mode_cache

std::bitset<NUM_VISION_MODES> Character::vision_mode_cache
protected

◆ vitamin_levels

std::map<vitamin_id, int> Character::vitamin_levels
protected

Current deficiency/excess quantity for each vitamin.

Definition at line 2208 of file character.h.

Referenced by load(), player::player(), store(), vitamin_get(), vitamin_mod(), and vitamin_set().

◆ worn

std::list<item> Character::worn

Definition at line 1569 of file character.h.

Referenced by absorb_hit(), active_light(), advanced_inventory_pane::add_items_from_area(), npc::adjust_worn(), allocated_invlets(), amount_worn(), best_shield(), bodypart_exposure(), can_swap(), can_takeoff(), can_wear(), debug_menu::character_edit_menu(), check_and_recover_morale(), check_art_charge_req(), check_item_encumbrance_flag(), relic_funcs::check_recharge_reqs(), consume(), covered_with_flag(), crafting_inventory(), deal_damage(), dispose_item(), npc::dispose_item(), exclusive_flag_coverage(), extended_description(), fire(), get_armor(), get_armor_bash_base(), get_armor_bullet_base(), get_armor_cut_base(), get_armor_type(), get_dependent_worn_items(), get_effective_efficiency(), player::get_eligible_containers_for_crafting(), item::get_encumber(), get_env_resist(), get_item_position(), get_overlay_ids(), get_weight(), hardcoded_effects(), has_artifact_with(), head_cloth_encumbrance(), i_at(), i_rem(), in_climate_control(), inv_dump(), character_funcs::is_bp_immune_to(), is_wearing(), is_wearing_active_optcloak(), is_wearing_active_power_armor(), is_wearing_helmet(), is_wearing_on_bp(), is_wearing_power_armor(), is_wearing_shoes(), is_worn(), item_encumb(), item_worn_with_flag(), load(), natural_attack_restricted_on(), item::on_wear(), map::player_in_field(), position_to_wear_new_item(), npc::print_info(), process_items(), item::process_tool(), remove_worn_items_with(), short_description_parts(), show_armor_layers_ui(), standard_npc::standard_npc(), starting_clothes(), player::store(), npc::stow_item(), swim_speed(), takeoff(), update_bodytemp(), set_transform_iuse::use(), use_amount(), volume_capacity_reduced_by(), npc::wear_if_wanted(), wear_item(), wearing_something_on(), weight_capacity(), weight_carried_reduced_by(), weather_effect::wet_player(), avatar::wield(), avatar_action::wield(), worn_with_flag(), and memorial_logger::write().


The documentation for this class was generated from the following files: